Azure AD: id_token as bearer token - azure

I have an application registered in Azure AD.
If I am using the same Application ID at the level of Web API and at the level of client (SPA application), why do both Azure AD auth libraries
(ADAL JS for Azure AD v1 and MSAL.js for Azure AD v2)
use ID token as bearer token when calling Web API, instead of requesting and using an access token? Doesn't this go against the spec?

According to official documentation and this might be your case.
"The OAuth 2.0 implicit flow in Azure AD is designed to return an ID token when the resource for which the token is being requested is the same as the client application. In other words, when the JS client uses ADAL JS to request a token for its own backend web API registered with same App ID as the client, an ID token is returned and cached by the library. Note that in this case the resource should be set to the App ID of the client (App ID URI will not work). This ID token can then be used as a bearer token in the calls to your application's backend API."
You can find more about this here!
https://github.com/AzureAD/azure-activedirectory-library-for-js/wiki/Acquire-tokens

Related

How to get JWT Token from Azure multi-tenant application?

I created a multi-tenant app on Azure Portal and sending request to get token with application's client Id. I am using the following URL to get token on Microsoft Azure AD
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
Sending a get request with parameters client_id={clientId}&response_type=token&scope=user.read+openid+profile+offline_access
However it is returning an access_token on given call-back url
http://localhost:8082/my-callback-url#access_token=EwCIA8l6BAAU6k7%2bXVQzkGyMv7VHB/h4cHbJYRAAATb8xtkaxI5xsVkWM6etOevj7ADopBYP1/hj%2bUz%2bf1ZXH4lpykHkES1XBRBDNRDWwdqAA%2brO2tFlMygiuusVx1EJKvqeV0rPPaNDNX9azpWGzS45BN6WmXKcxzX623enNYJOdo%2bYyTtaMipFapvABOsjHve1nVwfq9zqpmcldnIhXBeGefdQsgqmBNjeAyAbWzifLNtdz6Ybxnbt8nMY5adb82Z8tsfddfDdjrqk%2bu%2b85%2bxKXO9Xop3wdRvrVC9FM46RniA6H3NUKjOMTJAsX4IQLjGjXM4eq9o95lmSzF3zgFOXI1rYwkDRVsFsLOgP8tx0occDcuVPQgMalXR6JREDZgAACIJRWLYJGUcWWAKPx26NmroNGG1xEkPB1kLeGk0Hf8324YZs2InsGvQBFUMU4XzGGNdj0s5rLYKK2ictDstHV1daM241F1M5FiaX1qCgdRXneR9uPzUsSIBOzPJtT1dD4k%2bDxp6Nr4hEnDPlymp5X0SR4v5vUA3aRhnsvmEzBVQDKR7cFvT7NSqVHSr/tTv/epdx81qgJcd6S6xF8oaMc7mn76jgU4YBn8jXYnTfGhUvhNZ8RJyyl71AqZrGr7JS2kStselZUgjavLqc9DdQD9cwPSWu1ketKmGgCjt6lVB3nlaw8Wxq%2by2/YhPznTRFD2wj/vzDOdTzCcZ9mJV%2bKMGcXYQqBiGE0MF8%2bWA1EKSXniT5UiegTfJkvnsgtx6G6sdV0rzFM7Xa9d/dHNDfyV5oGedZtJXE1WCUrEIUZZm/HNhhQyh0WSG0gWm3vOY7NAs13vey9lcIQ6Fllu6W/Ty3HE4llFp/9a3lNcujmlxsCASFUOX6R54xPJMt1ipF5lh5uyZCPoUda46UsrCDnNRg0dhuoSVwJMDHzDbs4NXhX4nhTOze/9koz6p5Ao4DtJ20LqmcylZDoLxUhXIU5vvnBYpiHwanBt2E/rG%2bqVEQbRy/v9fhi0chY0XPzldIm/Lz2l0%2b0MpJ/4l53f9YTRLdEMD8X8Umi35ZvpK9arAqgdRkx4/oWG9m8sxOMY2eASetiAJaU8yjtETgHpBGJTXbDVDpNA1s5NGc9QC%2brcSnGDV0BKIDYxBISR8TiJQVUaPqbNU1Mj3kGyQFnfS0jS83VGVfFCZ4cHkhDq/awLh2JrR0Ag%3d%3d&token_type=bearer&expires_in=3600&scope=User.Read%20openid%20profile
How can I validate this access token? or how can I get a JWT token instead?
Your scopes are user.read+openid+profile+offline_access.
That first one is a Microsoft Graph API scope.
It's actually short-hand for https://graph.microsoft.com/user.read.
So you will get an access token that is meant for Microsoft Graph API.
The other scopes you defined affect the id token (openid, profile) or get you a refresh token (offline_access).
This means you cannot and should not validate the token.
Only Microsoft Graph API should be validating this token, since the token is meant for it.
If you want an access token for your API, you need to use a scope defined in the API's app registration (Expose an API section).

Azure AD B2C Resource Owner Password Credentials Authentication

In my application I want to call Azure Web API using Resource Owner Password Credential flow. I have implemented Azure AD b2c Auth for my Web API. I have created 2 Application in Azure, one for Web API and Native client App for ROPC. I gave WEB Api Access in ROPC app. I followed this article and got the Token from ROPC app. But when i pass my ROPC token to Web API I am getting 401. I dont know how to pass the scope of my web api scope in ROPC Token Request. Any help would be appreciated
Thanks in Advance,
Subbiah K
When you are requesting /token from Native APP (ROPC flow), you can add scopes in the request.
From the doc scope default set to
openid <ApplicationId/ClientId> offline_access
Modify this to like below to add scopes from Web API app. Make sure you should not put ClientId in scope
`openid https://tenant.onmicrosoft.com/hello/demo.read https://tenant.onmicrosoft.com/hello/user_impersonation offline_access`
Hope you already given API access (scopes) to Native Application.
Once you get access_token, that token will contain all the scopes you requested and you can send this to Web API to authorize.

How to authenticate a Web API to call Graph API with a token acquired by a client App

I am developing a client (React, typescript) application and a server (.Net Core) application. The api should make some calls to the microsoft graph api.
I have registered both apps in the Azure Active Directory and exposed the api with a permission. So on client side I am getting an access_token using msal.js with the given scope:
scopes = ["api://clientId/Test"]
So I am able to authorize in the api.
How should I gain access on the api side to consume the graph api?
Should I request a token in the client with scopes = ["User.Read", "api://clientId/Test"]?
Is it right what am doing to register the server app in azure as well? In the end could I have a token with only the scopes of Graph like scopes = ["User.Read", "Email.Read"] pass it to the Api and use this token on the api side to access graph?
After research I found that the solution was to use the on-behalf-of flow.
So basically an access token is retrieved from the client app with the scope that grants authorization over the server app. Then the server app is using this access token to create access tokens to get authorization for the Graph API.
Here the sample I used.

How to generate oauth token for webapi without using client id and client secret

I have deployed one webapi into azure. After that I have register my API into Azure AD.
I got my API client-id and client-secret, now i just want to test my API not like
3rd application will access it so what will be recourse id in this case.
I have used oauth for authentication into that webapi.
I want to test that webapi so into POSTMAN i used this url to generate oauth token
which i will pass as header Authentication bearer token.
step 1 -
https://login.microsoftonline.com/{{OAuth_Tenant}}/oauth2/token
in header -
grant_type:client_credentials
client_id:{{client_id}} // i have my API client-id
client_secret:{{client_secret}} // i have my API client-secret
resource:{{resource}} // i have my API client-id
when i generate token using above values and send that bearer token it fail error unauthorized.
You need to register an app in Azure Active Directory to acquire access tokens.
Register an app there, and you can find the client id/application id there.
Then you can create a key for the app, that's your client secret.
Finally the resource should be the client id or app id URI for your API's app registration in Azure AD.
To implement this according to best practices, you'll also want to look into defining app permissions for your API, so you can then assign privileges to apps to call your API.

MobileServiceClient InvokeApiAsync gets 401 while try to access asp.net core web api

I have a Xamarin Forms app that intereacts with a Asp.net Core Web api hosted on Azure App Service with client authentication flow with Azure B2C authentication.
The app can login succesfully to the Azure with the LoginAsyc (I get the idtoken) but when I try to invoke a service that requires authorization using the MobileServiceClient I get a 401. The api is called using the InvokeApiAsync.
If I invoke a an api method that does not require authorization it works fine.
I opened the Azure logs, and only see 401 error.
Any idea how to call this secure action method from Xamarin using the MobileServiceClient.
Please help
David
The app can login succesfully to the Azure with the LoginAsyc (I get the idtoken) but when I try to invoke a service that requires authorization using the MobileServiceClient I get a 401. The api is called using the InvokeApiAsync.
According to your description, I assumed that you are using App Service Authentication / Authorization. For Client-managed authentication, you directly contact the AAD identity provider and retrieve the id_token or access_token. At this time, you could just access the authorized endpoint as follows:
https://{your-app-name}.azurewebsites.net/api/values
Authorization: Bearer {aad id_token or access_token}
Note: When constructing the MobileServiceClient, you could pass your custom DelegatingHandler to append the bearer token before sending request(s) to your Azure backend.
I just created a single Native app in my B2C tenant and use MSAL to retrieve the id_token or access_token as follows:
var authority = "https://login.microsoftonline.com/tfp/{Tenant}/{Policy}";
PublicClientApplication IdentityClientApp = new PublicClientApplication("{native-app-id}", authority);
IdentityClientApp.RedirectUri = $"msal{native-app-id}://auth";
var scopes = new string[] {
//"https://bruceb2c.onmicrosoft.com/EasyAuthB2CApp/user.read"
""
};
var result=await IdentityClientApp.AcquireTokenAsync(scopes);
Note: I just created a single native app, the parameter scopes in AcquireTokenAsync method does not support the clientId, so I just pass the empty scopes, at this point, you would not receive the access_token, you just need to use the id_token as the bearer token to access your Web API. For the Web API web app, I used the native app to configure my AD authentication on Azure Portal.
Moreover, you could create a native aad app for your mobile client and a WebAPI aad app for your azure web app. At this time, you could specify the valid scopes for your native aad app to access the WebAPI app. Then, you would retrieve the access_token, at this time you need to set the WebAPI app id as the Client ID or add it to the ALLOWED TOKEN AUDIENCES list on Azure Portal.
In summary, you need to make sure the aud property in the id_token or access_token matches your Azure Active Directory Authentication Settings on Azure Portal. Note: You could use https://jwt.io/ to decode the token and check the related properties.
Moreover, for client flow authentication using LoginAsync, you need to pass the access_token to log in with your web app, then you would retrieve the authenticationToken. And the mobile client library would add the authenticationToken as the x-zumo-auth header to the subsequent requests (e.g. using MobileServiceClient.InvokeApiAsync).
Additionally, here are some tutorials, you could refer to them:
App Service Auth and Azure AD B2C
Integrate Azure AD B2C into a Xamarin forms app using MSAL
Azure AD B2C: Requesting access tokens
ASP.NET Core 2.0 web API with Azure AD B2C using JWT Bearer middleware

Resources