1

I use Postman to test my API hosted in Azure. First I get an Access Token like this

enter image description here

Since I use the grant_type ´client_credentialsI have to use the default scope like this api://my-app-id/.default` as explained here.

But one of the endpoint of my API requires a specific scope, so the call fails because my access token does not contain this scope.

How am I supposed to test from Postman with the required scope ?

Sam
  • 13,934
  • 26
  • 108
  • 194
  • You're API will be consumed by applications and / or users ? the `.default` scope should return all the assigned permissions. – Thomas Jun 23 '20 at 20:10
  • both. The returned token doesn't contain any scope at all. Surprisingly the call to my webapi works just fine for endpoints that do not require any particular scope – Sam Jun 23 '20 at 20:21
  • if the token is valid, there is no reason to be rejected. ihow did you grant specific permissions to your service principal ? – Thomas Jun 23 '20 at 21:13
  • App-only tokens will not have a `scp` claim, and may instead have a `roles` claim. – Carl Zhao Jun 24 '20 at 03:08

1 Answers1

3

If you use Client Credential Flow to obtain an access token for an api protected by Azure, you must create an application and grant application permissions to the application (this is because Client Credential flow has no user interaction).

Then you need to define the application permissions by editing the list of api applications.here is an example.

Next, grant application permissions to the application: enter image description here

Refer to this document and use Client Credential flow to get access token here:

1.First you need to get the administrator's consent:

GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions

enter image description here

2.Then you can get the access token by sharing the secret:

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=api://your-app-id/.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials

enter image description here

Parse the token and you will see your custom roles: enter image description here

Try using the token to access your API.

Update:

According to your mistakes, there is user interaction, so if you want to use a user token, you should not use Client Credential Flow but auth code flow, and grant client application Delegated permissions. enter image description here

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=api://11f5aca5-ba22-4b7b-8312-60a09aab7xxx/Files.Upload
&state=12345

enter image description here

POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=api://11f5aca5-ba22-4b7b-8312-60a09aab7df5/Files.Upload
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=JqQX2PNo9bpM0uEihUPzyrh  

enter image description here

Parse the token and you will see your custom scp: enter image description here

Carl Zhao
  • 8,543
  • 2
  • 11
  • 19
  • I see. So I have to create a dedicated app for postman and give that app permissions to my API , correct? Therefore the client ID I have to pass in the query string is the one of this new app, not the client id of the API ? – Sam Jun 24 '20 at 05:18
  • @Sam Yes, you need to create an application and pass the client ID of the application to access the API. – Carl Zhao Jun 24 '20 at 06:16
  • I followed every steps and now in my token I see I have the myTestRole in the roles array. However it still fails when calling a scope-protected endpoint with the error `The 'scope' claim does not contain scopes 'Files.Upload' or was not found` Files.Upload is one of the scope permission of the API I'm calling. What am I doing wrong here ? – Sam Jun 24 '20 at 07:11
  • I have a feeling I have to change my API to check against AppRoles and not just Scopes because Scopes seem to be intended for users only. However since I'm testing my API with postman, it means I have to make it compatible with both users and apps. Accordingly to this doc I found anyway : https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-verification-scope-app-roles Am I correct ? – Sam Jun 24 '20 at 07:18
  • @Sam According to your mistakes, there is user interaction, so if you want to use a user token, you should not use Client Credential Flow but auth code flow https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow, and grant client application Delegated permissions. I will update the answer later. – Carl Zhao Jun 24 '20 at 07:51
  • my idea was to use auth code flow when coming from a webapp, when I have a signed-in user, and to use Client Credential Flow when coming from Postman (for test purpose only). In the API code, I have a check on the scopes and if they are not found I fallback on checking for the PostmanRole I've created per your recommendation above. If the role is not there, then I throw an exception. It is working fine. But you are suggesting I should not do this, right ? – Sam Jun 24 '20 at 07:55
  • @Sam Your idea is ok, but you should make a judgment on ''The'scope' claim does not contain scopes'Files.Upload' or was not found'' in the code, if there is no'scope', you should go to find'Role', Instead of throwing an exception directly. – Carl Zhao Jun 24 '20 at 09:32
  • 1
    @Sam Hi,I updated some of the answers. If you think my answer is helpful to you, you can mark him as the answer. – Carl Zhao Jun 24 '20 at 09:41
  • Thanks, I will try this soon and I'll let you know. I can already mark this as answered because as I mentioned above it is working with they hybrid solution i've come up with based on your first recommendation – Sam Jun 24 '20 at 11:53