Azure AD B2C how to configure the "aud" claim - azure

I am new to the Azure ecosystem and I am a bit lost.
I use Azure AD B2C to secure multiple Spring Boot applications but I have a strange behavior, it seems like a token is tied to a specific application, which is not really convenient, because that means we have to manage multiple tokens, one per application. On each application I have this configuration:
azure:
activedirectory:
b2c:
base-uri: https://<tenant>.b2clogin.com/
tenant-id: <tenant-id>
client-id: <client-id>
user-flows:
sign-up-or-sign-in: B2C_1_signin_signup
Example, I have a user UserA which wants to consume ApplicationA, ApplicationC and ApplicationD. UserA relies on ApplicationB(front end app) to ask a token using the grant_type=password.
When I use the granted access token I can only consume one application. If I try to use the same token in another application I have a HTTP 401 with this message in application logs:
The aud claim is not valid
The issue is, when we ask a token we can only specify one scope, the scope value should contain the application that should consume the token.
My question is: how can we use one token for multiple resource servers? How can I configure Azure AD B2C to add all applications in the aud claim so that the token is recognized by the resource server?
Thank you

The requested scope determines which API the access token can be used at. The access token aud claim will be set to the client id of the respective scope.
You can use the refresh token you acquired in the first authentication to request an access token for a different scope.
The subsequent scope you request as part of a refresh token call, must be granted as a permission under the first application (app registration) that you authenticated to. It doesn’t matter which scope was requested in the initial authentication at this point.

Related

getting custom claims in Access Token for Client Server application in Azure AD?

We have a client-server application that targets enterprise use cases mostly. We want to test if Azure AD is a valid IDP for our application that now supports authorization code flow but may be developed to support for authorization code with PKCE.
Our requirement is that we need 'preferred_username' and 'groups' as claims in the jwt based access tokens. The client application is a desktop based app (Win & linux) that authenticates users using any IDP speaking authorization code flow.
For POC, I used a trial account from Azure ad with default set of users in azure ad. Created security groups in the Azure Ad portal and added users to those groups. I registered apps as desktop/mobile based platforms and with an arbitrary redirect url. Under Token configuration, I added 'preferred_username' in access token as optional claim and 'groups' as part of both ID and Access Tokens.
I have set following in the application manifest:
"accessTokenAcceptedVersion": 2,
But these claims are never listed in the access tokens but only appear in ID token.
Is it possible to get these claims in access tokens, so the resultant access tokens can be used by our application?
Tried: Authorization code flow with PKCE for desktop/mobile app.
Expected claims preferred_username and groups in jwt Access token.
TLDR; Following below article, I am expecting an Access Token for my server:
https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-permissions-to-access-your-web-api
In my understanding:
Client App ---> Client App on Azure (with scope perms to Web Api)
Server App ---> Web API App on Azure (exposing scope)
CLient App permissions
Also, I think I am dealing with 2 issues here:
Get Custom Claims in Access Token with Authorization code (or Auth code + PKCE)
Access Token should be meant for my application ( and not MS Graph)
When creating a App registration, you have to add
groupMembershipClaims": "SecurityGroup",
To your manifest to access the security groups
https://learn.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-fed-group-claims
If you creating a enterprise application you can add Attributes & Claims within the single sign on settings.

Azure AAD App can access Admin App without granting permission using a token

I have two Azure Ad Apps:
1) Admin/BackendApp which guards my webapi
2) Consumer APP which will consume my webapi
When i try to access my web api using the token created using below URL passing the required ClientID, ClientSecret, Resource and grant_type=client_credentials
https://login.microsoftonline.com/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/oauth2/token
i get access token from above url and pass that token as Authorization header to my webapi i get successfull response without granting any access to/from admin/backendapp.
You need to check for valid scopes/roles in the token!
Define delegated/app permissions for the API in Azure AD and enforce them in your API. A global check that the token contains at least one valid permission is good to have.
An app in any tenant can acquire a token for your API as long as they know your tenant id and client id.
If you do not check for permissions, your API is vulnerable!
I have an article for how to define and enforce scopes in ASP.NET Core: https://joonasw.net/view/azure-ad-authentication-aspnet-core-api-part-1
Based on your query, the JWT token is created to call the API already have enough permission to call the resources. This looks like a normal scenario

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

Microsoft Azure OAUTH2.0 - How can Multiple Source Clients call Azure OAUTH2.0 authentication

I create an Azure APIM instance, register it as an app in AD and then create a OAUTH2.0 server under APIM which is setup using the clientid/secret key of above registered app. I make a dummy API under this APIM and then protect it with this OAUTH2.0 server. I also add a JWT policy on my api to look for a token and authenticate against the tenant-id.(No claims mentioned).
Now lets say, i have a Customer (ABC) and for that i register another app in AD and create its Clientid/secret. Customer generates its token with the help of token endpoint (this endpoint is given under Endpoints tab of AD app registration option). Customer calls the API with this token and it works.
Issue: I didn't give any permission for my APIM App in AD to the Client App in AD but it still works, which essentially means that any Clientid/secret from any app registered in AD will go through my JWT policy of the API. Because it is just validating against the tenantid. How can we stop this and make sure that it works only for a customer to which permissions is given.
This is one of the major things I mentioned in my recent article: https://joonasw.net/view/azure-ad-authentication-aspnet-core-api-part-1.
Any app of type Web App/API in Azure AD can get a valid access token for any API in that Azure AD tenant.
Even before any permissions are given to it.
This is kind of a "feature" I guess.
Quote from the article:
If you only require an authenticated user, any confidential client in your Azure AD can acquire an access token for your API and call it. So it is important that you implement the user_impersonation scope check at minimum.
Now since your caller will call your API as itself, you need to implement an App Permission.
You can see how those are defined here: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Then implement a check that ensures the roles claim contains the value of the app permission you defined.
The claim will be a string array, so some kind of contains check needs to be made.
This will then require that this app permission is granted the caller before they can make the call successfully.
If you also want to allow delegated calls (i.e. calls on behalf of a user),
then add an optional requirement for the user_impersonation scope.
Those are stored in a single string claim (scp), space-separated.
So for that one you'll need a contains check on the string.

Azure AD - Differentiate between App token and User token

I am building a asp.net webapi which is protected by Azure AD Oauth bearer token authentication. I am using Azure AD Bearer token validation OWIN middle-ware to validate the token and extract the claims.
I have a requirement to differentiate when a request is coming from a service context and when the request coming from user context. I am aware that App Tokens (Issued by AD for a APP context) will not have any UPN claims using which i can easily identify but i was wondering is their any standard way to do this?
Quoting from an internal forum:
The appidacr claim indicates the type of client authentication performed. For a confidential client, the value is 1 when a shared secret (a password) is used as a client secret and 2 when a certificate is used as a client secret. The value 0 indicates a public client, which does not provide a client secret and therefore does not authenticate to the STS. Since confidential clients can acquire both user delegated and app only access tokens, the appidacr claim alone does not help to distinguish a user token from an app-only token.
If you want to distinguish between app-only access tokens, user-delegated access tokens, and id tokens issued by Azure AD (all of which are JWTs signed by the same key), follow this guidance:
First of all, validate the ver claim's value is 1.0.
Next, check to see if the JWT is an access token or an id token. The most reliable way to distinguish between the two is the presence of the appid and appidacr claims. These claims will be present in access tokens, but not id tokens.
If the JWT is an id token, then it represents a user. The subject of an id token issued by Azure AD is always a user. Never accept an id token as proof of authentication, always require an access token.
If the JWT is an access token, the presence of an scp (scope) claim informs you that the token is a user delegated access token. The value of the scp claim tells you what authorization the client has been granted by the user.
If the access token does not have an scp claim, it is an app-only access token. In this case, it may have a roles claim.
Don't rely on UPN and email claims to determine the type of token, they're not as reliable.
Per the Microsoft Docs
Your application may receive tokens on behalf of a user (the usual flow) or directly from an application (through the client credentials flow). These app-only tokens indicate that this call is coming from an application and does not have a user backing it. These tokens are handled largely the same, with some differences:
App-only tokens will not have a scp claim, and may instead have a roles claim. This is where application permission (as opposed to delegated permissions) will be recorded. For more information about delegated and application permissions, see permission and consent in v1.0 and v2.0.
Many human-specific claims will be missing, such as name or upn.
The sub and oid claims will be the same.
Personally in my code, to determine if a token is an App token, I use a combination of checking that the claims: "oid" and "sub" both exist and are the same, as well as checking that the token does not contain a name claim.
In practice I have found that tokens issued using different flows can contain different claims, which is why I have found using a combination of a couple of these properties can lead to better being able to differentiate between a user and application token.
There is now a supported way of telling whether or not the token is for an App or not.
Azure Ad supports the configuring of access tokens, for your protected resource to have some optional claims. The claim needed to answer "Is token for App?" is "idtyp"
See Configuring optional claims for how to set it up

Resources