Authorized calls for Azure B2C user - azure

I'm trying to have a user login using an Azure B2C custom policy, and then use the token that is passed to the redirect URI to make authorized calls to our APIs. I'm aware that the token given after logging in is an id token, but I haven't seen a way to exchange it for an access token.
Using the id token worked for Azure API management, but not in logic apps as it expects the issuer to be login.microsoftonline.com.
Is there a way that I can exchange the user's id token for an access token, or a better way to secure endpoints so that only logged-in B2C users can access them?

Azure AD B2C supports both the id token and access token where id token contains claims that you can use to identify users in your application and access token are used to identify the granted permissions to your APIs.
There is no way to exchange id token for an access token, but you can request for the tokens in the request by passing id_token+token in the response_type while authenticate the request.
GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=xxxx
&response_type=id_token+token
&redirect_uri=https://www.jwt.ms
&response_mode=fragment
&scope=openid%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345

Related

Azure AD returns non JWT Tokens when exchanging the OAuth2 code for an access token

I have an Azure AD App on my tenant that is configured to accept multiple tenants AND personal accounts.
I follow the procedure to retrieve an AccessToken as explained here: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
When I receive the "code" in my app from the Microsoft web page, I exchange it for an access token calling the endpoint "https://login.microsoftonline.com/common/oauth2/v2.0/token".
Here the behavior differs whether the user that logs in is a work account or a personal account.
With work accounts, I receive a normal JWT Token and everybody is happy: I can decode the token and read the claims.
With personal accounts, I receive another token, that is not a JWT Token and I don't have any clue on how to:
validate this token
read a few information from the user (specifically, the email of the user)
Could you please help me understand how to perform these two actions?
NOTE: I have seen the answers here: Microsoft as OAuth2 provider for personal accounts does not issue JWT access tokens but my case is slightly different, since I don't want to access MS Graph with this token, I just need to retrieve the email of the user.
Thanks!
cghersi
The access_token in OAuth2 is not required to be an JWT per the OAuth specification.
However Microsoft supports OpenID Connect, that provides an id_token. The id_token is always an JWT.
To "upgrade" your OAuth request to an OpenID Connect request you simply have to add the scope openid (and possibly email to ensure you get an email).
Then when you exchange your code to an access_token you also get an id_token

Azure AD OAuth Client Credentials Grant flow

Trying to set up Azure AD OAuth client credentials grant flow for my web api. I'm following the document in https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow. I have to expose my API to a 3rd party. I've created the APP in Azure AD (this is for the client that is requesting my API), generated the secrets and was able to get a response from oauth2/token endpoint. My questions are below:
What is the best way to validate the token? Is it by passing the JWT
(bearer token) as a HTTP header to my API, and then using the SDK to
validate the token
(System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler)? I'm using
C#.
What is the significance of Azure AD -> App Registrations -> "My
API App" -> under Manage, Expose an API? It has an option to
"Authorize client applications". How could I use this feature to
conditionally block and approve the client applications?
I will have to share the secret, client id and the App Id Uri with the 3rd party for them to generate the token and I will validate the token when I receive it.
You're on the right track.
This answer, Azure AD OAuth client credentials grant flow with Web API AuthorizeAttribute Roles, will walk you through one way to do this, using the roles claim in the token to authorize the call.
You will need to:
define roles
create an App registration for each 3rd party
assign their application to your desired roles
You can then use the AuthorizeAttribute to map which roles can execute which controllers/actions, like so:
[Authorize(Roles = "Reader,Requester,Editor,Approver,Administrator")]
Token validation
Once you complete token obtaining flow, you receive a JWT bearer access token. From token consuming end (your service), you need to perform a JWT validation. This is done by validating JWT signature and Claims. One of the most important claim you validate is the audience (aud) claim which must be the identifier (ex:- your service's URL, an ID) unique to token receiving service. Where you register this ? That's your second question.
Please read through MS's guide on token validation which explains key points - Microsoft identity platform access tokens
Service registration
This is where you register valid token receivable endpoints (ex:- your api app). If you check your token request, you provide resource parameter which must match to registered identifier. This allows Azure to validate the token request and issue an access token the mentioned resource. You find this as aud claim in the token. Hope you got the connection now.
App secret
No, only the token obtaining party require the client credentials. Your API or any token consuming party does not need the secret. They only require a valid access token and token signing certificate details. certificate details are exposed at jwks_uri in openid-configuration endpoint.

What is the logic behind validating a user entity with Microsft Graph/Azure AD as the the authenticator of my API?

I already made the authentication flow with the Microsoft Graph/Azure AD authentication. Once I get the authenticated user's token I store them in his cookies. To validate the user's token I call the Microsft Graph API resource /me. This does not seem a good approach because basically everytime time a client does a request to my API, he is basically doing 2 requests because my API requests Azure AD for validation.
Is this a good flow?
No, it isn't.
Your front-end should acquire an access token for your API, which the API can verify using its digital signature.
The token will contain some info about the user as well as the app that acquired it.
The way in which the front-end acquires the token depends on the type of application.
Front-end single page apps use implicit grant flow for example.
Do note that you have to specifically ask for an access token for your API.
As long as your back-end is then configured with standard JWT Bearer authentication,
all is handled.
This is done by specifying the authority as your Azure AD tenant (or the common endpoint if it's multi-tenant),
and the standard bits for JWT authentication should download the public keys from Azure AD's metadata endpoint, which it can then use to verify validity of any access token it receives.
You do not have to validate tokens for an api that's not yours (issued to your AppId Uri).
For example, Graph validates the tokens that are sent to it (issued for "https://graph.microsoft.com).
If you build and register in Azure AD an Api of your own (say AppIdUri="https://myapi.mydomain.com"), your clients will request and receive access tokens with aud claim set to "https://myapi.mydomain.com".
The clients themselves don't need to validate the access token issued for your Api But your Api, when it receives those access tokens, has to validate them. The validations, among other things will validate the access token was issued to "https://myapi.mydomain.com".
Try out this sample, to get a good understanding around concepts of token validation.

Azure Ad access token clarifications

I need clarification with sample or reference link for below items:
How to enable automatic renewal of access token?
How to get active access token and expiry time ?
Is there any possible ways to get Ad username, password and client id again from access token?
How to validate access token ?
It all needs to be implement in c# not in powershell.
How to enable automatic renewal of access token?
Upon successful authentication , Azure AD returns two tokens: a JWT access token and a JWT refresh token .When the access token expires, the client application will receive an error that indicates the user needs to authenticate again. If the application has a valid refresh token, it can be used to acquire a new access token without prompting the user to sign in again. If the refresh token expires, the application will need to interactively authenticate the user once again.
How to get active access token and expiry time ?
For how to authenticate users and get an Azure AD access token for your azure ad app , you could refer to Authentication Scenarios for Azure AD .The Azure Active Directory Authentication Library (ADAL) enables client application developers to easily authenticate users to cloud or on-premises Active Directory (AD), and obtain access tokens for securing API calls. ADAL is available on a variety of platforms. You could find code samples and common scenario in this document .
Is there any possible ways to get Ad username, password and client id again from access token?
You could get decode the access token , find the upn claim which Stores the user name of the user principal ; appid claim identifies the application that is using the token to access a resource. Please refer to document :Azure AD token reference .And of course ,you can't get password information .
How to validate access token ?
JWT tokens are signed, but not encrypted when received. It must validate the signature to prove the token's authenticity and validate a few claims in the token to prove its validity. The claims validated by an app vary depending on scenario requirements, but there are some common claim validations that your app must perform in every scenario.For example, we need to verify the iss and aud claim if you were developing a single tenant app. And you also need to verify the nbf to ensure the token is not expired. For more details , please refer to Validating tokens .
Here is a code sample for how to manually validating a JWT access token in a web API . And if you were using the OWIN components in your project, it is more easy to verify the token by using UseWindowsAzureActiveDirectoryBearerAuthentication extension , code sample here is for your reference .

How to programatically generate Bearer Token using Azure AD when Multifactor Authentication is enabled

I am following the example https://github.com/Azure-Samples/active-directory-dotnet-native-headless to authenticate a user against Azure AD in which the user sends his user credentials (uname,pwd) to acquire a bearer access Token(grant_type set to password). This token will be sent in the Authorization header to the internal Rest API. The REST API uses the token to get the details of the user using ClaimPrincipal and to authorize the user against AD Security group using Graph-API.
Now the problem is, we have Multi factor authentication (MFA) enabled, in this case how shall I able to generate the Token using Azure Oath APIs and get the above program to work.

Resources