Getting the scopes and audiences correct when calling an API in Azure AD B2C
This is a typical use case within B2C. You have a client application (web or native) and this application needs to call an API.
The API is protected i.e. it requires an OAuth Bearer token and the functionality that the API can perform is controlled by scopes (permissions).
You set this all up and when you call the API you get “Not authorised” and you proceed to spend the rest of the day banging your head against a wall 😃
We have two applications, B2CTest (the client) and B2CAPI (the API that the client calls).
B2C Test — Application ID = 47840c35-e986–468b-8d2c-e25aa02d3d08
B2C API — Application ID = ecfb57af-c76a-49a0-b48f-37311846956f
Creating the API:
Note the “App ID URI”. We set this to “b2capi”.
Under “API access”, we select “openid” (use OpenID Connect and return a JWT token) and “offline_access” (return a refresh token).
Under “Published scopes”, we create two new scopes viz. “read” and “write”.
Note the generated full scope value:
where “b2capi” is the “App ID URI” above.
On the client side under “API Access”, we add the B2CAPI API and then we select the scopes.
We don’t need to add any new scopes here.
Now let’s test it.
I use jwt.ms as the reply URL as this will display the JWT for us — a neat debugging tool.
Under “Access Tokens”, select the API and then select all the scopes.
B2C then generates the following URL for the “Run now endpoint”:
Note that the client_id (Application ID) is the ID of the application (B2CTest) not the API.
Note the full scope value.
When we run the policy and authenticate we get the JWT:
Note the “aud” (audience) is the application ID of the API which is exactly what we want.
The “scp” (scope) contains the three scopes we asked for.
The “”azp” (authorised party) contains the application ID of the client.
There’s a good overview here.