azp Claim Missing from Azure AD JWT - azure-active-directory

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.

Related

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

How can I pull various claims out of the access token?

I'm using the msal.js library to connect to Azure AD B2C for a reactjs client application.
I can login and get the access token. I can dump that token into jwt.io and see the claims that I've specified in my sign in policy. But I'm missing how I can pull the claim data out within the application.
Does the msal library have a method to extend the user to include those claims?
Looking at the examples to get the user's name I'm thinking something like...
clientApplication.getUser().myCustomClaim
Alternatively does anyone have any suggestions on the best way to pull that claim data out of the token?
EDIT: Referenced the "dev" commit.
In the "dev" branch, this commit adds the idToken property to the User object.
You can reference the identity token claims as follows:
clientApplication.getUser().idToken["mycustomclaim"]

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.

Postman - how to obtain Azure Active Directory token using sign in form?

Is is possible to obtain an AAD token in Postman by letting the user to Sign In using the standard AAD sign in form?
I know how to obtain token using the request to AAD (grant_type = client_credentials) but such a token does not have a UPN (user identity).
I would like to somehow type in my credentials in Postman and get the token. So it is a manual interaction, the user(me) needs to manually sign in - the same way how ie. Visual Studio verifies your identity.
Postman now offers the ability to "Authorize using browser." You'll need to make changes to your AAD application to support it in addition to configuring Postman.
Configure your AAD application
Add a redirect URI to your AAD application for Postman to receive the authorization code. In the AAD Portal, navigate to your app registration, then to the "Authentication" tab, then add https://oauth.pstmn.io/v1/callback as a new redirect URI. This URI was provided by Postman when you check the ✅ Authorize using browser box (below) and is also documented on their website.
Configure Postman
You can set this up under "Authorization" for a single request, a folder of requests, or a Collection. Open the "Authorization" tab and select OAuth 2.0. Under the "Configure New Token" section, enter the following information:
Token Name: anything you want. I chose the name of the AAD application.
Grant Type: Authorization Code (With PKCE)
Callback URL: check the ✅ Authorize using browser box
Auth URL: copy this from the AAD portal under Overview > Endpoints (on top bar) > OAuth 2.0 authorization endpoint (v2). Mine looks like https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize
Access token URL: copy this from the AAD portal under Overview > Endpoints (on top bar) > OAuth 2.0 token endpoint (v2). Mine looks like https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token
Client ID: copy this from the AAD portal under Overview. It's also commonly referred to as an "Application ID" and is a GUID.
Client Secret: leave blank (not used by this grant type)
Code Challenge Method: SHA-256
Code Verifier: leave blank or provide your own
Scope: the scopes you're requesting in your token, separated by spaces
State: leave blank or provide a value such as a random GUID.
Client Authentication: Send as Basic Auth Header (not used by this grant type)
Refer to Postman's documentation on OAuth 2.0 options for more information.
Get a token
Click Get New Access Token to open the auth flow in your machine's default web browser. After authentication, it should redirect back to the Postman application and a new token will be created with the name you provided earlier for "Token Name." Select "Use Token" in the top-right corner of the popup to copy it into your current token. If the token expires and your requests start failing authorization (probably a 401 or 403 error), you can revisit this tab and get a new access token.
Occasionally, you may want to visit Current Token > Access Token > Manage Tokens > Delete > Expired tokens, otherwise you'll be inundated with nearly-identical tokens.
Postman cannot popup the sign in page as it only does HTTP requests. As you stated, it can do confidential client flows.
What you could do is hand-construct an auth request, sign in, and grab the auth code. Then take that auth code and drop it into the Postman authorization form, and let it hit the Azure AD token endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/token
The Azure AD protocol referene will be super helpful for you.
I think if you're wanting to quickly generate Access Tokens your best bet is to pick a framework/language and build a lightweight app that gets and logs tokens. Azure AD has a Python Flask sample for the v2 endpoint that takes 5 minutes to setup and could be converted to printing out access tokens. If you want to use v1, you can checkout the list of samples at the Azure AD developer guide.

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