Azure AD - how to obtain v2 access token - azure-active-directory

Using Azure AD, OIDC implicit flow, I can obtain an access token from a v2 endpoint.
The authorization endpoint I am using looks like this:
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id>&redirect_uri=https://localhost:44321/signin-oidc&response_type=id_token%20token&scope=openid%20api%3A%2F%2Fdev-api-gateway%2FAtlas&response_mode=form_post&nonce=123
Yet, it seems that I get a 'v1' access token.
What am I doing wrong?

Thank you for enlightening me that there are differences in how an App (representing the Resource) is registered.
Basically the difference itself is made by the 'accessTokenAcceptedVersion' field in the App's Manifest.
Initially it was 'null' but I've changed it to '2' (as below).
According to docs, the 'null' value should as well permit v2 tokens - it is a issue on AAD's side, in 'Open' state.
Thanks for the lead on this issue.
Regarding the way an app is registered, there is indeed a difference:
- if it was done in azure portal than the 'accessTokenAcceptedVersion' field of manifest is set to 'null'
- if it was done in the app registration portal (https://apps.dev.microsoft.com) than it defaults to '2'
If there wouldn't be the issue (bug) mentioned above, this shouldn't make a difference.

The acquired token version is related to your access resource that is protected by v1 endpoint or v2 endpoint.
On my side, the API is protected in v2 endpoint, so it returned the v2 access_token.
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id>&redirect_uri=https://snv2app.azurewebsites.net&response_type=id_token+token&scope=openid api://f3d966c0-517e-4e13-a5bb-9777a916b1a0/User.read&response_mode=fragment&nonce=123
And to parse access_token:

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.

Swaggerbuckle with AAD --Error AADSTS500013: Resource identifier is not provided

I'm trying to use AzureAD to get a token in swagger and test my .netCore2.1 API with it.(using Swashbuckle.AspNetCore 4.0.1)
To do this I completed the following steps
1. Created a Web API project(asp.net Core2.1)
2. Register an Azure AD (AAD) app for the Web API
3. Updated the Web API project to use Azure AD authentication
4. Register an AAD app for the Swagger web site https://localhost:5001/swagger
5. Granted permissions for the Swagger AAD app to access the Web API AAD app
6. Generated a Client Secret for the Swagger AAD app
7. Enabled OAuth2 implicit flow on the Swagger AAD app
8. Added Swagger to the Web API project
When I authenticate, I am getting the following error.
Error AADSTS500013: Resource identifier is not provided .
When I click authorize
I am getting error AADSTS500013: Resource identifier is not provided.
My WebAPI project's startup.cs file goes here
Please help me understand which resource Identifier I am missing here or how to resolve this error.
Or any pointers on how to use Swaggerbuckle with ASP.NET Core webAPI, especially with AAD authenticated WebAPI ?
UPDATES
I copied my webAPI's APPID URI from azure portal. ie Dashboard>>Microsoft - App registrations>>MY_API_APP>>Settings>>Properties>>App ID URI
But I am still getting the same error when I try to authenticate
Error AADSTS500013: Resource identifier is not provided
Usually resource identifier which uniquely identifies your application. You can easily found your resource Identifier Like below:
When logged into the Azure portal, Azure Active Directory > App Registrations > [App Name] > Settings> Properties, then it's the App ID URI
See the screen shot:
In the orignal OAuth 2.0 specification, there is no resource parameter in the authorization request. It use scope parameter. The authorization and token endpoints allow the client to specify the scope of the access request using the "scope" request parameter.
As document explains, when Azure AD implement the OAuth 2.0(1.0 endpoint), the resource is used to specify the access_token you request for which resource. And the Azure AD will issue the token which the scp based on the permission you config on the portal for the resource.
And in the v2.0 endpoint, the Azure AD also use the scope to support the dynamic permission request. More detail you can have a look here.
Usual Reason for Error
Make sure you have configured below steps accordingly.
Like below:
Application Manifest
Reply URI
Request Endpoint
For V1.0 refer this URI https://login.microsoft.com//oauth2/authorize
For V2.0 refer this URI https://login.microsoft.com//oauth2/v2.0/authorize
Application Consent
Need to confirm your application required resource access permission you could refer here
I believe this step can lead you to sort out your problem.
With Azure AD V1.0 app you need set resource to identify which api you want to access during the authentication&access token requests :
Code flow :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Implicit flow :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-implicit-grant-flow
In Swashbuckle.AspNetCore 4.0.1 , you need to config the resource as parameter if you want to get access token for accessing your web api :
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MySite API V1");
options.OAuthClientId("19c73866-562f-482a-bafb-89d9fe9b0aaa");
options.OAuthAppName("Swagger Api Calls");
// add resource
options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>() { { "resource", "f479db30-9b62-431b-98c2-bcaae52203cf" } });
});
For us Nan Yu's response got us one step closer.
We added the resource in the AdditionalQuerystringParams like so:
options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>() { { "resource", "{ResourceIDHere}" } });
We are now able to get passed the Auth step in Swagger, but trying routes out doesn't seem to pass the token to the api called and so we get a 401 Error.
change { "scope", API_AppID_URI} to { "resource", API_AppID_URI}

How to specify Resource URI when acquiring access token for Azure AD V2 endpoint?

I have used ADAL.js in a previous project which supported only work accounts and am able to successfully acquire idtokens and then accesstokens to an API (ResourceURI: "https://myresource.com"). Works fine.
Now, I am trying to use MSAL.js for another project because there I need to support both work accounts (aad auth) and personal "Microsoft Accounts" (MSA). I am running into problems now trying to do the same thing as in my ADAL project.
The concept of "Resource" has seemingly vanished from AAD V2. So how does one specify the Resource url when acquiring an access token to the target API? So that the resulting accesstoken contains the ResourceURI in the AUD claim (which will be enforced by the API I am calling).
If I force add the Resource querystring parameter, thusly:
msalapp.acquireTokenSilent([], null, null, "resource=https%3A%2F%2Fmyresource.com")
I get the following error:
AADSTS901002: The 'resource' request parameter is not supported.
Documentation says to use SCOPE instead. But using:
msalapp.acquireTokenSilent(['https://myresource.com'])
results in:
AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://myresource.com openid profile is not valid. The scope format is invalid. Scope must be in a valid URI form <https://example/scope> or a valid Guid <guid/scope>..
So: how do I specify the Resource URI when acquiring the access tokens when working with the v2 endpoint via MSAL.js? Sorry the (usually pretty good) MSDN articles are not useful at all in this case...
In Azure AD v2.0 you need to use scopes, not resources.
If you have a resource, and want to get a token for all the permissions, you can use :
https://myresource.com/.default.
You can also be more fine grain: more information is available from https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Adal-to-Msal#scopes-for-a-v10-application (this is in C#, but the translation is straightforward)

Trying to access a v2 endpoint hosted webapi but no luck, true if only graph api works on v2 now?

Had a webapi running on v2 endpoint, the intent was to get access through a single call to both graph and the custom webapi, was using the v2 auth code grant flow, the url using as below,
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=14e9111f3e1-d220-415d-9bf4-d089f0b5feff&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A8081%2Fartifactory%2Fwebapp%2Fsaml%2FloginResponse&response_mode=query&scope=api%3A%2F%2F14e9f3e1-d220-415d-9bf4-d089f0b5feff%2Faccess_as_user%20https%3A%2F%2Fgraph.windows.net%2Fuser.read%20openid%20offline_access&state=12345
with the scope as
api://14e9f3e1-d220-415d-9bf4-d089f0b5feff/access_as_user https://graph.windows.net/user.read openid offline_access
However, keep failing with a invalid scope error. If I take out the custom webapi from the resource, everything went through wonderfully.
Reading further, there is a limitation for webpi that
Web API can receive tokens only from an application that has the same Application ID. You cannot access a Web API from a client that has a different Application ID.
So I am confused, how to archieve the goal to use v2 endpoint to authenticate and get access to both graph and webapi????
--edit
the error message is 'AADSTS65005: The application 'blah' asked for scope 'user.read' that doesn't exist on the resource. Contact the app vendor.'
Today the v2 endpoint cannot issue an access token for a custom API. The feature is in active development, but there's no ETA to share.
Also note: even when the feature will be available, you will not be able to reuse the same access token across multiple resources; you'll be able to consent for multiple resources at once, so that your user is only promoted once, but you will need to request access tokens for each resources separately.

Resources