Azure AD token validation - why validate issuer? - azure

I have an API service that uses Azure AD tokens for authentication and authorization. I plan to use https://github.com/AzureAD/passport-azure-ad library for this and need to use BearerStrategy - https://github.com/AzureAD/passport-azure-ad#42-bearerstrategy. I'm confused by the validateIssuer property.
validateIssuer and issuer configurations need to be used together if I understand the docs correctly. issuer is a URL that contains the tenant id and the AD version(1 or 2) used to issue the token.
As the API service who will validate token, why would the API service care about the AD version that was used to issue the token? And hence why would it validate the issuer url, when it should care only about the tenant id? I'm trying to understand why must the entire issuer url be verified and not just the tenant id.

In the API service the validators are defined in the library source file like Microsoft.IdentityModel.Tokens/Validators.cs. which validates the token based on the token validation parameters (Issuer, ValidateIssuer, signature etc..).
The issuer contains the URL for the actual tenant with the v1.0 and v2.0 endpoints.
Tokens always needs to match the endpoint they're requested from, and the tokens always match the format expected by the Web API your client will call using that token.
Why You need to validate the issuer because many services can generate tokens but you only want to trust certain source(s).
If we leave ValidateIssuer then middleware will not try to validate the issuer tenant and it would effectively mean that your application is open for anyone with a user in Azure AD.
For more information about the token validation please refer the documents Validateissuer and issuer

Related

AzureADB2C Client Credentials Grant with Client Assertion as Opposed to Static Secret

I have a requirement to provide API to our consumers. The intention is to secure the API using AzureAD B2C - Client Credential Grant flow.
I have created a custom policy on B2C tenant that provides the access token. Things work fine with the clientId and Secret authentication method.
I now want to secure the OAuth2 conversation further by allowing the client to use the signed client_assertion as opposed to static client secret using their protected key. I have uploaded the public portion of the key into the relevant app registration.
Unfortunately, consuming the /token endpoint with the signed client_assertion results in an error.
REQUEST
https://tenant.b2clogin.com/tenant.onmicrosoft.com/b2c_1a_demo_clientcredentialsflow/oauth2/v2.0/token
grant_type=client_credentials&scope=https%3A%2F%2Fapi%2F.default&client_id=d5339984-e6c7-457a-9ef9-21fb6e3e6c59&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJo
RESPONSE
HTTP/1.1 400 Bad Request
{"error":"invalid_request","error_description":"AADB2C99027: Policy 'B2C_1A_Demo_ClientCredentialsFlow' does not contain a AuthorizationTechnicalProfile with a corresponding ClientAssertionType.\r\nCorrelation ID: 5eb76fa5-c919-4877-a722-0d38408e18c6\r\nTimestamp: 2023-01-19 07:38:25Z\r\n"}
Can someone please tell me if B2C is intended to support client assertions? Metadata JSON on the policy returns only the following two authentication methods:
"token_endpoint_auth_methods_supported": [ "client_secret_post", "client_secret_basic" ]
Is it possible to include private_key_jwt as a supported authentication method using custom policy configuration? Is it possible to configure the AuthorizationTechnicalProfile for the policy with a corresponding ClientAssertionType?
I hope that I have explained the problem well enough.
I have tried various strategies, incluling the use of AAD token endpoint, login.microsoftonline.com with the B2C tenant Id. Using that endpoint, the custom policy on B2C is completely ignored, therefore generating a vanilla token with none of my curated claims.
TLDR: As of June 2022, Azure AD B2C does not support client assertions.
This issue on Github asks for documentation for error number AADB2C99027. In the course of the discussion, a member of the team states
Unfortunately, we decommissioned client_assertion flow because it didn't follow OIDC spec – So we shouldn't be documenting the error.
From that, I take that there are no plans to support client_assertion flow.

Validating Azure B2C Token in app that didn't authenticate user

I have a scenario whereby, a user would sign in/sign up to Azure AD B2C from a frontend application. There after they would make calls to an API application (with a JWT token) separate from this frontend. The requirement is that the API application validates a user's token and decides whether to execute the request. I can send the JWT token from frontend to API using the auth header. I can receive it in the API also. The challenge is to now validate that this token is not faked by a man-in-the-middle or just being abused by someone who got hold of it. I know each token comes with a timestamp and can be checked for expiration. However, this is not sufficient. I need to check it against Azure AD B2C somehow.
Update: the API is a NodeJs based Azure Functions app
You can validate the signatures of the token in your API app. A Token is signed by asymmetric keys.
Every user flow in AzureB2C has a associated metadata document which has all the details about the keys in the tag "jwks_uri"
"jwks_uri": "https://xxxxxx.b2clogin.com/xxxxxxxxx.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_pe",
you can fetch the key details from the link under jwks_uri tag and use it to validate the signature. Also remember these keys are rotated so you need to get the latest once every 24 hours.
Sample :-
https://github.com/azure-ad-b2c/samples/tree/master/policies/user_info
Doc https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview
See this sample. The API is protected using the UseOAuthBearerAuthentication to verify the signature of the token. All Azure AD B2C tokens are signed JWTs. The sample code will find the metadata endpoint of your policy+tenant combination, and use the public key to ensure that the token signature is valid/unmodified and has been signed by the private keyholder (AAD B2C)

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.

How check token received from Azure Active Directory?

Let's say that a user logs in using the Microsoft login page and Azure requests application url with token. But how to validate it? Anybody can request application url with fake token. Does Azure API contain url for such a check?
But how to validate it?
To validate an id_token or an access_token, your app should validate both the token's signature and the claims. To validate access tokens, your app should also validate the issuer, the audience, and the signing tokens. These need to be validated against the values in the OpenID discovery document. For example, the tenant-independent version of the document is located at https://login.microsoftonline.com/common/.well-known/openid-configuration.
The Azure AD middleware has built-in capabilities for validating access tokens, and you can browse through the samples to find one in the language of your choice. For more information on how to explicitly validate a JWT token, see the manual JWT validation sample.
For more details, you could refer to Validating tokens.

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 .

Resources