1
votes

I am making OAuth 2.0 auth code authentication flow with multi-tenant application. Here is my authorize url: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=my_id&prompt=consent&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauthorize&response_type=code&scope=openid+offline_access&state=17

It goes fine and I receive auth_code. Then I make request with this auth_code to token_url and receive a lot of information, like:

  1. token_type
  2. scope
  3. id_token
  4. access_token
  5. refresh_token
  6. expires_at
  7. ext_expires_in

Seems fine to me, but when I make request on API with access_token like: https://management.azure.com/subscriptions/my_sub_id/locations?api-version=2016-06-01 with headers:

Content-Type:
  - application/json
Authorization:
  - Bearer EwBQA8l6BAAURSN/FHlDW5xN74t6GzbtsBBeBUYAAV1IHgHb4dOWblzfd/YsSuFicAMDYbua17QivnAT9/pIaeKAg3uKsK5VGqWLzjMOUQrCpd7R1RAM6RkzI0u8e4rpO7DISG7qLso5H5+U1jb+38/j1urcwlXMMxhy83ZXmdpkLXpZV+vcOV...

It responds with 401 error

body:
  encoding: UTF-8
  string: '{"error":{"code":"InvalidAuthenticationToken","message":"The access token is invalid."}}'

To be honest I think something wrong with my access_token. It seems not like JWT for me. Documentation says it looks like:

"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCEV1Q..."

But my access_token looks like:

"access_token": "EwBYA8l6BAAURSN/FHlDW5xN74t6GzbtsBBeBUYAAZDe7JE/MPLoAi+Fr+1Xxq5eBe5N9l8Q+c4QjkY5PGEzRnBpPe7+v6h+PLdh1cceBQx+/JsB2QCrYSCt7x/zGsQAhwoY/"

Is it fine?

Here is my permissions for application: Permissions

1
Try to add your service principal in your subscription, navigate to your subscription in the portal -> Access control (IAM) -> Add -> Add role assignment, add it as a role(e.g. owner). - Joy Wang-MSFT
Also, try to include the https://management.azure.com/ in the scope, both when you request the authorization code and access token, see this link: docs.microsoft.com/en-us/azure/active-directory/develop/… - Joy Wang-MSFT
This https://management.azure.com/ is not a valid scope it says. I guess I need to set proper scope. - Roman Alekseiev

1 Answers

0
votes

The main issue you have here is that you have only asked for an access token for the scopes openid offline_access. The resulting access token will be for Microsoft Graph (https://graph.microsoft.com), not for the Azure REST API (https://management.azure.com).

To indicate you would like a token for a given API, the scope parameter in your authorization request should include the delegated permission you would like the app to have for the API. In the case of Azure REST API, there's only one delegated permission: user_impersonation. The identifier URI for the Azure REST API is https://management.azure.com, so the scope value you want to use is:

openid offline_access https://management.azure.com/user_impersonation

Two more important notes:

  1. As you've discovered, you will not always be issued an access token as a JWT which you can decode peek at. The format of the access token is an agreement between the service which issued the token (Azure AD or Microsoft Accounts, in this case), and the service for which the token was issued (Microsoft Graph, in this example).
  2. You should not always include prompt=consent. prompt=consent should only be used if you have already tried signing in the user without the user needs to be re-prompted for consent for a new permission.

    If you simply include the required scopes in the scopes parameter, the Microsoft Identity platform will take care of figuring out if it needs to prompt for consent or not. If you always include prompt=consent, you will find that many organizations will be blocked from accessing your app, because they've disabled the ability for users to grant consent themselves (and this parameter specifically states that you require the user to be prompted again).