Azure AD - return roles and groups in token SPA application - azure

I created an Angular application with Implicit Grant Flow for authentication and a Web Api in .Net Core 3.1 following this tutorial: https://github.com/Azure-Samples/ms-identity-javascript-angular-spa-aspnetcore-webapi
The problem is: I need to return the roles and/or groups of the logged User within the Bearer Token to authorize my API, but I'm not being able to do so.
I added the roles to the App Registrations Manifest here, added the claim 'groups' in the Token Configuration menu and set the "User assignment required?" as yes in my Enterprise App Configuration.
Even with all these configurations, I'm not able to return the roles/groups claims in the bearer token.
Example of the token the authentication returns:
{
"ver": "2.0",
"iss": "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0",
"sub": "AAAAAAAAAAAAAAAAAAAAABTOBMzzWB5LS36oSmQMgyc",
"aud": "ecb5e87f-6f34-4f05-8e8d-8d6149178926",
"exp": 1597173984,
"iat": 1597170084,
"nbf": 1597170084,
"name": "name",
"preferred_username": "email#outlook.com",
"oid": "00000000-0000-0000-fa54-d112egdce65a",
"tid": "9188040d-6c67-4c5b-b112-36a304b643ad",
"azp": "edeb4b7d-9cac-4f3b-a21d-ead77993689e",
"scp": "access_as_user",
"azpacr": "0",
"aio": "DYNhHjG*PSY1ceuC11yaLYcLta8zh49iA!l2UCbCsH9QlaUkEHVQ4paQFRmb!qv7J6yTbAQItGWDgCW9UgUipz4Xnma*DOkFFDNIZ5lkffThD*ie91XMzZIoPhUPwNHOt5dLrw3VASE2WCvJfvDFOQk$"
}
Am I doing something wrong? Is there any other way to authorize the logged user in a SPA Application, return the token with the roles and groups and send it to the Web Api?

You should add the App Role into the manifest of the service app (TodoListAPI) rather than the client app (TodoListSPA).
Don't forget the assign the App Role to the users.
This should be able to fix your issue.

Hi You need go to azure ad -> app registrations -> your app -> taken configuration -> Add Groups Claim -> then select Security groups checkbox. Save. Then log out log in again and should be in taken under groups.

Related

Azure Ad B2C vs Keycloak

I have a question regarding keycloak and Azure Ad b2c. Both offres authentication with different identity providers. Main difference I can see is in authorization. With Keycloak I can easily manage claims and roles of users via admin portal. In Azure B2c it looks very hard (setting custom policies) maintaining all the data via custom created app. Am I missing something? Relying app is strongly cloud native (Azure of course) and thats why I'm thinking about azure b2c. Relying app will strongly use roles and claims also.
What do you think about these two identity solutions (pros and cons).
What is the easiest way to manage implemented (by custom policies) user claims and roles in azure b2c? (do I have to write separate management app by myself or there is easiesy solution?)
Edit: first conclusion is that right nów azure requires separate app for connecting to graphapi (via rest or using sdk). Keycloak has it built in. Any pros of using b2c in this case (for c# dev)?
You don't have to use custom policies to use custom claims. Below an example :
On your B2C tenant, go to Azure AD B2C > Manage > User attributes and create a custom attribute; here a client ID attribute :
Then Azure AD B2C > Policies > User flows and create a flow, for example "Sign In" :
Use the recommended flow :
During the flow's creation, at the last steps, you can specific what claim will be included in the returned jwt token on Sign in; select our custom attribute Client ID :
Then when I login into my application using a B2C account, I have the below JWT token returned :
JWT token's payload, base64 decoded :
{
"iss": "https://mytenant.b2clogin.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/v2.0/",
"exp": 1664181788,
"nbf": 1664178188,
"aud": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"oid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"sub": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"extension_ClientID": 1,
"name": "myUserName",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_SI",
"nonce": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"scp": "user_impersonation",
"azp": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"ver": "1.0",
"iat": 1664178188
}
I have set the "extension_ClientID": 1 using the msGraph API but this could also be done using a SignUp flow.

Using client credential flow on Graph api returns an access_token without scopes

Here is what my goal is: I would like to get an access_token from within my api. Currently I am trying to get the access token using the client credentials flow:
And I successfully get a response:
But this response does nothing because when I use the access_token as authorization parameter in a GraphApi endpoint I get an error response saying I am missing scp or roles parameters. I have roles defined and approved from an administrator from the application. What could be the problem?
Here is the decoded jwt access_token:
{
"aud": "a********************ed5",
"iss": "https://sts.windows.net/**********4f-d6b581dd3836/",
"iat": 1660825101,
"nbf": 1660825101,
"exp": 1660829001,
"aio": "E2ZgYPits***********g8R9TAA==",
"appid": "eabbd3*************da6990ed5",
"appidacr": "1",
"idp": "https://sts.windows.net/5a8f9d89-81da-4218-884f-d6b581dd3836/",
"oid": "77e***************8085325",
"rh": "0.AYEAiZ2PWtqBGEKIT9a1gd04NuDTu-rpzyZCiMRhXaaZDtWBAAA.",
"sub": "77e4***************48085325",
"tid": "5a8f9d89-8*****************581dd3836",
"uti": "nl-kk3T*******w2ePAA",
"ver": "1.0"
}
I tried to reproduce the same in my environment and got the below results:
I created one App Role named DemoRole for my Azure AD application like below:
Go to Azure Portal -> Azure Active Directory -> App Registrations -> Your App -> App Roles
I assigned that DemoRole to few users like below:
Go to Azure -> Azure Active Directory -> Enterprise Applications -> Your App -> Users and groups
Now, I generated access token with parameters like below:
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
client_id = xxxx-xxxx-xxxx
grant_type = client_credentials
client_secret = ***************
scope = api://xxxxxxx.xxxx.com/.default
Response:
When I decoded the token, I'm also unable to get the roles like below:
To get roles claim in decoded token, make sure to add your custom API permissions and grant admin consent like below:
Go to your Application -> API permissions -> Add a permission -> My APIs -> Your App Name -> Application Permissions
After granting the admin consent, I generated the access token again and got the roles claim in the decoded token like below:

Azure AD, When I use custom domain in Azure WebApp to access, I can't get the correct token

I built a WebApp on Microsoft Azure, this WebApp needs to access a WebApi to get data, I used Azure AD authentication, everything works fine, but when I bind a custom domain to this WebApp, I go to use This custom domain to access the Token obtained by the WebApp is not correct.
Correct and incorrect token comparison:
Correct:
"aud": "api://[client id]",
"scp": "user_impersonation",
incorrect:
"nonce": "2o-O2KpKPQekxB_vLD9myPz2zq4n333dUphtn7FhJk",
"aud": "00000003-0000-0000-c000-000000000000",
"scp": "email openid profile",

Scope is not being added to Access Token returned from Azure Ad

Overview
We have an Azure AD secured API living in Azure as a web app. We need to be able to:
Trigger this API via user interaction from a client application (this part works).
Trigger this API programmatically from a scheduled job that will simply get a token & hit this API (this part does not work due to authentication issues).
Problem
The issue is that when we request a token from Azure AD, scope is not being set in our token claims resulting in the API rejecting the token.
This is the request we are making:
This request returns an access token with the following claims:
{
"aud": "<our api client id>",
"iss": "https://login.microsoftonline.com/<tenantId>/v2.0",
"iat": 1644421512,
"nbf": 1644421512,
"exp": 1644425412,
"aio": "<value>",
"azp": "<scheduled job client id>",
"azpacr": "1",
"oid": "<guid>",
"rh": "<value>",
"sub": "<guid>",
"tid": "<guid>",
"uti": "<value>",
"ver": "2.0"
}
As you can see scp (scope) is not included in the token claims even though we include it in the request.
If we use this token to make a request to our API we get the following error:
System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token.
Any help on how we can get an access token from Azure AD with the proper scope/permissions to call our API, would be greatly appreciated.
Note
The Azure AD App Registration for our scheduled job that will request a token and then hit our API, does have the Delegated API Permission access_as_user which you can see I am including in the token request's scope.
The above is expected as using client credentials you can't get the delegated permissions i.e. the access_as_user permission and also the scope in client credentials should be used as api://<APP_ID>/.default . So , If you want delegated permissions then you will have to use implicit grant flow instead of client credentials.
For testing , I created two app registrations , One on which API is exposed (Postman) and other which is to be used for authentication (Powershelltest) and then , I have tested the same in 2 different scenarios like one for client credentials and another for implicit grant :
Main APP whose API has been exposed :
App used for authentication:
Scenario 1 Using Client Credential flow :
Scenario 2 using Implicit Grant flow :

Microsoft graph and Azure Ad user authentication

I have an application registered in Azure ad.
When i do ADAL with the following details i get a authoriazation token to use with microsoft graph api.
`username = 'admin#domain.com'
password = 'password123'
client_id = application id from azure ad
client_secret = keys from application on azure ad
tenant = directory id from azure ad`
Using this token i can fetch the list of all sites in my sharepoint account.
Below is the endpoint i call to fetch the sites with the bearer token:
https://graph.microsoft.com/v1.0/sites?search=*
But when I just do the client authentication using token generated using below endpoint Iam not able to access the sites list.
login.microsoftonline.com/tenant_id/oauth2/v2.0/token
`grant_type : client_credentials
clientid : client_id
clientsecrte : client_secret
scope : https://graph.microsoft.com`
It does not return all of the sites.
Is there a way of getting all sites list with just client authentication.
Or can i get a token for user authentication without user password.
Here is the token decoded that i am using:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/586145ec-0428-4da6-8061-fb114257ab70/",
"iat": 1528949458,
"nbf": 1528949458,
"exp": 1528953358,
"aio": "Y2dgYLh*************xAAA=",
"app_displayname": "App Name",
"appid": "504ddb16-2899-48be-be57-**********",
"appidacr": "1",
"idp": "https://sts.windows.net/586145ec-0428-4da6-8061-fb114257ab70/",
"oid": "afcf166f-24c2-49f1-b285-b672d0413c50",
"roles": [
"Sites.Read.All",
"Sites.ReadWrite.All",
"Sites.Manage.All",
"Sites.FullControl.All",
],
"sub": "afcf166f-24c2-49f1-b285-b672d0413c50",
"tid": "586145ec-0428-4da6-8061-fb114257ab70",
"uti": "hwYd8FZCH0KruWGRFiIHAA",
"ver": "1.0"
}
I get other permissions also but these are site related in Microsoft Graph api
Cause:
The successful one is using ROPC flow and it can get delegated permissions onbehlaf of the user. But the failed one is using client_credentials flow which get application permissions and cannot onbehlf of the user.
Updated Answer
Solution:(Before you do this test, ensure you have SPO license in your tenant)
Try to add Sites.Read.All Application permission in your registrated AAD Application and do admin consent for it before you getting token.
If you're using AAD v1 endpoint, you can do admin consent by clicking Grant permissions button.If you're using v2 endpoint, please input this kind of URL in your internet browser to do admin grant:
https://login.microsoftonline.com/{yourtenant}/adminconsent?client_id={the applicationid of your client}&state=123&redirect_uri={the redirect uri of your app}
and sign in with Global admin account and accept this permission.
In my test lab, I used v2 endpoint.Here is the token I got via Postman:
Here is decoded token in https://jwt.ms , we can decoded the token to ensure it has the permissions we want.
Then I use this token in the head to call Microsoft Graph API and succeeded:
For more detials about Site permission for Microsoft Graph, please refer to this documentation.
Please let me know if this helps!

Resources