Azure B2C token scope permission issue - azure

When I try to get a token with a scope inside it then I get a This application does not have sufficient permissions against this web resource to perform the operation error.
Failing call:
https://xx.b2clogin.com/xx.onmicrosoft.com/oauth2/v2.0/authorize?p=somepolicy&client_id=xx-xx&redirect_uri=https://localhost:7223/&scope=https://xx.onmicrosoft.com/xx-xx/Some.Scope&response_type=token
I can call it with the openid scope but then there are no scopes in the token. As I understand you need to set the response_type=token and scope to the actual scope of your api.
Working call but no scopes
https://xx.b2clogin.com/xx.onmicrosoft.com/oauth2/v2.0/authorize?p=somepolicy&client_id=xx-xx&redirect_uri=https://localhost:7223/&scope=openid&response_type=id_token
I've alreay added the API to the permissions of the client and granted admin consent so that can't be the issue.
What am I doing wrong here? Or is it maybe not possible to use scopes with a B2C token?

I have tried in my environment, and I got the token successfully.
To resolve the error, please check the below steps:
In my case, I added a scope named “newscope” and then granted API permissions like below:
Go to Azure portal -> Azure AD B2C -> App registrations ->Your application -> Expose an API -> Add Scope
To get token, try with below URL:
https://xxxxx.b2clogin.com/xxxxx.onmicrosoft.com/oauth2/v2.0/authorize?p=somepolicy&client_id=your_app_id&nonce=defaultnonce&redirect_uri=https://jwt.io&scope=openid profile offline_access&response_type=token&prompt=login
With the above authorization URL, I got the token like below that displayed the scopes successfully after decoding.
Please make sure to add additional scope like profile, offline_access along with open_id.
Here I have given response_type=token instead of id_token
In Authentication blade, make sure to check mark both access token and id token.
If still something goes wrong, try with lower case scopes.

Related

Implemented Azure AD Client Creds flow but failing while validating the access token on the server end due to missing 'scp' property

Registered the App in Azure AD and followed client credentials grant.
Implemented the below to fetch the access token
https://github.com/Azure-Samples/ms-identity-javascript-nodejs-console
Implemented the below to validate the access token
https://github.com/playerony/validate-azure-ad-token
While running the validate azure ad token, experiencing this error "Error: The token's payload does not contain "scp" property". Need help in resolving the same.
Establishing API1(client end) accessing another API2(server end) on different platform. Registered API2 on Azure AD and defined client secrets. As provided the implementation links for fetching the access token and validating the access token, i am seeing "Error: The token's payload does not contain "scp" property".
The error , the token's payload does not contain "scp" property" occurs when application permissions are not granted admin consent by Administrator.
I did not receive scopes which are nothing but roles when application permissions are given.
It Is because they are not granted admin consent.
When they are given a proper consent through portal by admin or during users login .
Then they can be seen. So while calling other API please make sure you have each of the scopes given admin consent granted .
Then you can see them reflected in token which is used to call API:
Please make sure to give scopes with /.default when using client_credential flow.
Example: api://xxxxxxx/.default
Make sure to check mark Id_token in authentication blade .

Azure APIM oAuth workflow - refresh token is missing

I enabled oAuth in Azure API management. Then using ClientId, Client Secret, Scope, Access Token URL & Grant Type, I was able to get the access token. How can I get the refresh token from the API ?
To get refresh token from the API, you need to add offline_access permission in the scope.
Please note that, Client credentials flow works with permissions of Application type only. So, you won't get refresh token using this flow as offline_access permission is of Delegated type.
Instead, you can make use of Authorization Code flow as Grant Type.
I tried to reproduce the same in my environment via Postman and got below results:
In my Azure AD application, I added API permissions like below:
To get refresh token, change the grant type to Authorization Code and include offline_access in the scope like below:
When you selected Get New Access Token, one new window will open where you have to login with your credentials as below:
After successful authentication, you will get both access token and refresh token like below:
You don't have to make two separate calls like one to get access token and another one to get refresh token.
Instead, you can directly add offline_access in the scope along with custom Api scope.

Resource Owner Password Credentials token results in 401 on Azure Function App

I would like to use the Resource Owner Password Credential Flow of Azure AD for my function app. The function app is up and running. Once I configure Azure AD authentication for the app, my requests get rejected with a 401 Unauthorized but with no further details on the error.
I should also emphasize that I can obtain new tokens from the authentication endpoint for my tenant. It's just that these tokens get rejected when I try to call the function from curl. When I login with the browser and the same credentials, I can access the function.
Clarification: Obtaining tokens via the API works but these tokens are then rejected by the function app's AAD authentification. Going through the browser, I obtain tokens that can log me into the function app.
What I did:
Create a function app
Basic GET request, works with either no authorization or with authorization through the browser.
Create an app registration in Azure AD
Implicit grant: Access + ID Token
Supported account types: Single Tenant
Allow public client flow: Yes
In the manifest: "oauth2AllowImplicitFlow": true,
Scopes: Custom user_impersonation scope for my API
API: Here I added my function app with the user_impersonation scope
Configure the function app to authenticate user through AAD
Management mode: Advanced
Client ID: The client ID of the app registration above
Allowed Token Audiences: The URL of my function
Steps to reproduce:
Obtain a new access_token:
Issue a POST request to https://login.microsoftonline.com//oauth2/v2.0/token and the following parameters:
clientId: The client ID of the app registration in Azure AD
scope: user.read openid profile offline_access https://<my-function>.azurewebsites.net/user_impersonation
username: The e-mail address of the user
password: The password of the user
grant_type: password
This returns the access_token. I'm not going to post it here, but I can share details on request.
Call the protected API
Issue a GET request to https://<my-function>.azurewebsites.net/api/test with the following header parameter:
Authorization: Bearer <access_token>
Any help is greatly appreciated of course. It is important to note that users should not be able to login interactively anyway. I'm well aware of the pitfalls and shortcomings of the ROPC flow but this is the only way to solve this particular use case with Azure AD.
Here are some resouces I consulted before. I might have overlooked a critical point of course:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc?tabs=app-reg-ga (Not using AAD B2C but is probably similar enough. However the steps mentioned here work.)
I seem to have fixed it. The solution was a lot of trial an error, maybe there is an easier way.
Azure AD App Registration
Only select the access token, we don't need an ID token anyway.
Set "accessTokenAcceptedVersion": 2 in the manifest
Use the suggested api://... Application ID
Function App
Set both the Client ID and the Allowed Token Audience to the Application ID from the AAD App Registration, but without the leading api:// scheme.
Obtaining the token
Specify the scope as api://.../user_impersonation
After going through all of the steps above, I can successfully authenticate before being able to access my function app. The next challenge will be to read the authenticated user name from the request. But that might be the topic of another thread on SO.

Why is an Azure permission missing from the scopes of my JWT token?

I have a problem regarding the permission granted to my app by the user showing up as a scope in my JWT.
I want to allow the user to see a list of his tenants (Office 365) on my page. For this I need a token with the https://management.azure.com/user_impersonation scope. I added the permission to the Azure API Permissions. When the user first logs in he sees this:
From this screen I assume my setup works, since the user gets asked to grant my app permission for what I need (Access Azure Service Management as you). But when I paste the JWT on the JWT Debugger I don't see the scope user_impersonation among the scopes.
I get this:
I already tried to remove the app from the test-user's applications (in their Azure Portal) to get it to ask again for consent but it's still the same. Other test users have also the same result.
What I'd need is simply to see user_impersonation among the scopes. That would allow me to call the API endpoint that returns a list of my user's tenants.
You need to acquire the access token for the https://management.azure.com resource.
Or if using v2, request it for the https://management.azure.com/user_impersonation scope.
That looks like an MS Graph API token.
An access token is always only valid for one API, so you need to ask for a token for the Azure Management API.
It works now!
So, I tried to get scopes for both https://management.azure.com/ and https://graph.microsoft.com/ in one single token. As Juunas explained, you have to get a separate token for each API. But can ask consent for both at the same time though.
My flow is this now:
I log the user in while asking him to consent to some permissions (for both API's and on first login only)
I request a token in the background for the Graph API scopes
I request a second token for the Azure Management API scopes

Wrong scope being returned when requesting token

I'm trying to build an O365 service status portal for users in my company. Only admins can see the admin portal status page, but we want to provide that info to our users/display on a dashboard.
I've registered the app in Azure, and given it the correct permissions according to the documentation. I can request an auth code and I'm able to use it to retrieve a JWT, but when the token is returned to me, I'm only seeing User.Read in the scope, meaning I'm unable to use it for any of the functions in the ServiceComms API.
Here's the snip of code being used to retrieve the token:
url = 'https://login.microsoftonline.com/<tenantid>/oauth2/token'
r = requests.post(url, dict(resource='<appid>',
client_id='<clientid>',
redirect_uri='http://x.x.x.x/365/auth/index.htm',
client_secret='<itsasecret>',
grant_type='authorization_code',
code=auth_code))
Here's the first part of what's returned:
{"token_type":"Bearer","scope":"User.Read","expires_in":"3600","ext_expires_in":"0","expires_on":"1525266602","not_before":"1525262702",
The account being used to retrieve the auth code initially is a global admin on the tenant, so would expect that this would be fine, but I'm new to this, so probably wrong.
Does anyone have any ideas?
Thanks.
I'm assuming that you've set the appropriate permissions on your app registration in the Azure portal, and your question is why they don't show up in the token.
I've seen this behavior before with the Azure v1 endpoint if the user you login with had previously consented to the User.Read permission, then you updated the required permissions in the portal. While it's logical to assume that Azure would detect this change and re-prompt, it doesn't. It keeps returning tokens based on the previously recorded consent and doesn't pick up the new ones.
To handle this, your app must include the prompt=consent query parameter on the URL during the authorization phase. That should force consent when the user logs in and pick up the new permissions.

Resources