AddMicrosoftIdentityWebApi .net core 5 web api ? will this support version V1 and V2 Api ? MSAL - azure-active-directory

i m using react my front end using ADAL.js and my back end using
MSAL ### below is code
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"))
as my front app use ADAL.js its create V1 token and in back end i have MSAL ?
how i can support this situation ?
as i want to impose my back end to understand V1 token which is created by front app ADAL.js

Yes, it is possible to request an V1 access token and even V2 depending on the requirement. .
But please check which token the API needs as:
Idtoken: If you ask for an ID token from the V1 endpoint, you get a V1 ID token. If you ask for an ID token from the V2
endpoint you get a V2 ID token.
Accesstoken: Access Tokens versions are determined by the configuration of your application/API in the manifest.
The access token type (v1 or v2) which is issued to your app is determined by the application registration of the resource API.
You can determine which type of tokens your API is configured to accept making small change or seeing what is present in app registration. In portal,when you go to the "Manifest" section, and check for "accessTokenAcceptedVersion". If it is set to null or 1, then all client applications requesting access tokens to call this resource will get a v1 access token (Regardless if they use MSAL or ADAL to request the access token).
And you may need to request a scope with /.default for example: https://database.windows.net//.default
According to Scopes for v1.0 apps (MSAL) | Microsoft Docs
NOTE:
For ADAL with a v1.0 access token , aud=resource
For MSAL accepting v2.0 tokens, aud=resource.AppId
For MSAL v2.0 endpoint getting an access token for a resource that accepts a v1.0 access token (which is the case above), Azure AD
parses the desired audience from the requested scope by taking
everything before the last slash and using it as the resource
identifier. Therefore, if https://database.windows.net expects an
audience of https://example.com/, you'll need to request a
scope of https://example.com/.default
Reference : authentication - Is it possible to obtain an Azure AD V1 token using MSAL? - Stack Overflow

Related

Changing AAD accessTokenAcceptedVersion does not result in token version change

I created a new app registration for an app service resource and the accessTokenAcceptedVersion was set to 2 by default (or may be due to my choices). Some clients got an access token for this resource and is being potentially cached on that client.
Later I changed the accessTokenAcceptedVersion to null (i.e. default 1). Now those clients fail to authenticate to the resource (rightfully so) given they have a cached v2 token.
The client in this case is an azure function using the AzureServiceTokenProvider library for getting & caching tokens. So I tried various ways to invalidate the cache involving :
Restarting the function
Waiting out for 1 day (the token expiration time)
Making changes to the app registration
Unfortunately Revoke-AzureADUserAllRefreshToken doesn't seem to work for managed identities.
But I'm still getting a V2 token. What can be done to invalidate this cache or to force a V1 token somehow? I'm trying to do this without any code change currently. But can deploy a change if needed at all.
On other machines/infra I'm able to get a V1 token for the same resource using the different identity. As per my understanding, the token version purely only depends on accessTokenAcceptedVersion. Nothing else.
Please check below points:
If you have changed the accessTokenAcceptedVersion to ‘null’ value, it may also permit v2.0 tokens – It is an issue on AAD’s side. It also depends on the way the app is registered. The difference is that:
If it was done using Azure Portal, then the 'accessTokenAcceptedVersion' field of manifest is set to 'null'
If it was done in the App Registration portal(https://apps.dev.microsoft.com), then it may point to version ‘2.0’
Also check :
The v1 authorization endpoint : https://login.microsoftonline.com/tenantid/oauth2/authorize?
The v1 token endpoint : https://login.microsoftonline.com/tenantid/oauth2/token
Try to change the authority and instance to v1 endpoint in the code and also wherever it is used in the code.
See Microsoft identity platform access tokens - Microsoft identity platform | Microsoft Docs
Both v1 and v2.0 endpoints have their own parameters separately. The v2.0 endpoint expect the ‘scope’ parameter in the request, whereas v1 endpoint expect ‘resource’. So do check the scopes for the api you are referring to and change the code accordingly.
If you still get v2.0 tokens, you must clear the cache of the client application calling your API otherwise until the token has expired, token would be taken from the cache, and would still be a v2.0 token. For that, you may try to call AcquireTokenSilentAsync (in the client while calling you Web API) to force the refresh.
Reference:
Wrong version of access token (got Azure AD V1 instead of V2) GitHub

azp Claim Missing from Azure AD JWT

I have registered an app with Azure AD and can get JWT's but I am receiving claims associated to V1 JWT's according to this whilst I am expecting claims associated to V2 JWT's.
More specifically, I would like to add the azp claim which is only available under V2.
I've followed these instructions to add azp but it is not available to add as an optional claim. I am under the impression that I'm using a version 2 app since the endpoints end with /V2 and I also have the ability to add the ipaddr which is only available for V2 apps as far as I understand.
Can anyone point me to what I am missing?
The version of the access token has nothing to do with the endpoint you use to request the token, but is related to the resource you requested. The default version of ms graph api is the token of version 1.0. If you want to obtain the 2.0 version of the token, you should request your custom api.
First, you need to create an application that represents the api, and then expose the api protected by Azure.
Next,under 'API permissions', give your front-end application access to your backend api:
Under 'API permissions' click on 'Add permission', then click on the
'My APIs' tab.
Find your backend application and select the appropriate scope.
Click 'Add permissions'.
Grant admin consent for your APIs.
Next, go to the manifest of the front-end application and set the accessTokenAcceptedVersion attribute to: 2.
Next, you need to use the auth code flow to obtain an access token,which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.
Parse the token, it will display azp claim and v2.0 version.

ID tokens vs Access tokens in implicit grant flow

I would like some clarification on how to use ID tokens and access tokens in an implicit grant flow.
I have an Angular SPA using MSAL.js for Angular package and a Web API. The API does NOT call any external services, like MSFT Graph. The back end uses role claims from JWT to establish RBAC authorization to our API functionality only.
This doc says:
https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens
id_tokens are sent to the client application as part of an OpenID Connect flow. They can be sent along side or instead of an access token, and are used by the client to authenticate the user.
ID Tokens should be used to validate that a user is who they claim to be and get additional useful information about them - it shouldn't be used for authorization in place of an access token.
This doc shows an authentication flow where a web API is called with an ID token instead of an access token:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow
This sample code sends ID token too (calling own Web API sample):
https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi-v2
The sample back end validates ID token audience against Client ID of the app that issued it.
Given our API is the only consumer of tokens, should we use ID tokens or access tokens?
Generally speaking, when securing your API with the Microsoft Identity platform, clients should be using the access token when making API requests, not the ID token.
check this part
It first calls acquireTokenSlient, which gets a token from the cache if available if not
it calls acquireTokenPopUp which will get an acces token for the specific scope, I am not sure if it would open up a popup window or will get a token in the background with hidden iframe. But it would fetch an access token for sure. API can never be accessed with ID token.
check https://learn.microsoft.com/bs-latn-ba/azure/active-directory/develop/scenario-spa-acquire-token for more clarification

How to get user info with a valid Bearer Token?

At work we are making an SPFx Web Part React client app that deploys to SharePoint as a Web Part. Our back-end is a ASP.NET Core 2.2 Web API that is secured using Azure Portal's built in Authentication feature. The front-end is using AadHttpClient that magically handles the authentication by taking the context of the current page (SharePoint) that has the user already logged in. Doing so, silent authentication occurs and the API call is successfully made with authentication successfully passed. The AadHttpClient is supposed to magically bundle up the token in the request header that gets sent to the back-end Web API. I still need to debug the live development app and see how to retrieve the Bearer Token in the back-end Web API. These are my next probable steps?
Would I just probably use 'string bearerToken = Request.Headers.....;' or 'string bearerToken = Request.Headers["KeyValue"]' to get the token itself?
Assuming I can get this Bearer Token, how can I check the caller's user information? Is it just var userName = User.Identity.Name;? Or would I or could I use the token and some how make a call to Microsoft Graph API to view the user's info?
If you are using ASP.NET Core and using default authentication then things are bit easier. From documentation you can see that several tokens are injected in the request header based on Identity provider so in your case you have to look for following headers which Azure AD injects. These headers would contain ID Token which you would need to verify the claims and get user information.
X-MS-TOKEN-AAD-ID-TOKEN
X-MS-TOKEN-AAD-ACCESS-TOKEN
X-MS-TOKEN-AAD-EXPIRES-ON
X-MS-TOKEN-AAD-REFRESH-TOKEN
Ideally all the claims are injected automatically in ClaimsPrincipal
you can find more here
Official Docs
How To extract Token

Scope for multiple web apis

I have 2 web apis (A and B) on my b2c. Each one of them publishes their own permissions respectively (scopeA1, scopeA2) and (scopeB1, scopeB2).
On my web application (which already configured and have granted access permission on both apis and the 4 scopes), in order to get authorization code for both apis during authentication, I tried to set my OpenIdConnectAuthenticationOptionsin scope property to include the 4 scopes.
I got an error AADB2C90146: The scope 'scopeA1 scopeA2 scopeB1 scopeB2 openid offline_access' provided in request specifies more than one resource for an access token, which is not supported.
While if I specify only scopes for web api A or B, then it works as per this link
How can I get my web app to use both web apis even with granted permissions for both
Thanks for help
If the two web APIs are separate applications in Azure AD, then you need to request access tokens separately for them.
I'm not familiar with the sample you used as a starting point, but it looks like these lines are where you need to make your change:
// Retrieve the token using the provided scopes
ConfidentialClientApplication app = new ConfidentialClientApplication(authority, Startup.ClientId,
Startup.RedirectUri, credential,
new NaiveSessionCache(userObjectID, this.HttpContext));
AuthenticationResult result = await app.AcquireTokenSilentAsync(scope);
accessToken = result.Token;
You should create an app instance for each of your APIs, and acquire a token for each of them. Then, when you call the APIs somewhere else, use the correct access token in the Bearer authentication header.
I had the same issue and asked a similar question Extend MSAL to support multiple Web APIs
but i have not had an answer, basically to get around it in the short term i have made both my API's use the same authorization client ID + secret and therefore I can reuse the same scopes accross my APIS
its not what i want but if you want to use Azure AD B2C you need to get used to compromising for a while until the support is there
-- I would also say you are using an older version of MSAL which i am also using, im waiting until the version 1 release before upgrading again.
The github talks about using this format
https://github.com/AzureAD/microsoft-authentication-library-for-dotnet
Step 1: Add MSAL to your Solution/Project
Right click on your project > Manage packages.
Select include prerelease > search msal.
Select the Microsoft.Identity.Client package > install.
Step 2: Instantiate MSAL and Acquire a Token
Create a new PublicClientApplication instance. Make sure to fill in your
app/client id
PublicClientApplication myApp = new PublicClientApplication(CLIENT_ID);
Acquire a token
AuthenticationResult authenticationResult = await
myApp.AcquireTokenAsync(SCOPES).ConfigureAwait(false);
Step 3: Use the token!
The access token can now be used in an HTTP Bearer request.

Resources