Azure AD B2C Audience validation failed - azure

I'm trying to authenticate to my B2C AD tenant on Azure AD B2C. I'm using OAuth 2.0 on aspnet .NET 6
If I request a new bearer token using Client Id
0fdd4f3b-xxxx-xxxx-xxxx-3f84bd9d02ax
I get back an aud value
https://mysite.onmicrosoft.com/0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax
I'm using
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
If I use 0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax in my config, he tries to validate it by prefixing Client ID with api:// and the following exception:
IDX10214: Audience validation failed. Audiences: 'https://mysite.onmicrosoft.com/0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax'. Did not match: validationParameters.ValidAudience: 'api://0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax'
If I use https://mysite.onmicrosoft.com/0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax in my config, he tries to validate it by prefixing Client ID with api:// and the following exception:
IDX10214: Audience validation failed. Audiences: 'https://mysite.onmicrosoft.com/0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax'. Did not match: validationParameters.ValidAudience: 'api://https://mysite.onmicrosoft.com/0fdd4f3b-xxxx-xxxx-a438-3f84bd9d02ax'
Why is the value always prefixed with api:// ?

Ok, apparently Stack Overflow was my rubber ducky.
If your Application ID URI does not start with api:// you'll have to make a manual change to the manifest of your application and switch to access tokens version 2.
Then change the value of accessTokenAcceptedVersion from null to 2
Now you can go back to your local application configuration and set the value of ClientId to the GUID only not including https://xxx.onmicrosoft.com/.

Related

Azure AD B2C with OpenID Connect getting error AADB2C90238: The provided token does not contain a valid issuer

I added and configured an OpenID Connect Identity Provider.
I set the return URL in the provider correctly.
I'm using the "Sign up and Sign in" user flow -- not a custom policy.
Running through the user flow, I ultimately get redirected to my application .../MicrosoftIdentity/Account/Error (or if I set return url to jwt.ms, I get the same error) with the page indicating the error
AADB2C90238: The provided token does not contain a valid issuer
How can I even see the issuer in the token? (It's all handled inside AD B2C service).
I can see what's listed in the provider's .../.well-known/openid-configuration endpoint. I guess that's what's not matching in the token. I've seen suggestions of using Application Insights Logs to view the token -- but, apparently, that can only be done with custom policies.
Is there another way to tell AD B2C not to validate the issuer? Or is another way to handle this issue?
I tried to reproduce the same in my environment.
Open Id configuration is like below:
Where the metadata url is https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration
Authorization request looks like below:
https://kavyasarabojub2c.b2clogin.com/kavyasarabojub2c.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1_newSignupSignin&client_id=xxxxx5&nonce=defaultNonce&redirect_uri=https%3A%2F%2Fjwt.ms&scope=openid&response_type=id_token&prompt=login
I received the same error :
With redirect uri: https://jwt.ms
Error: invalid_request
AADB2C90238: The provided token does not contain a valid issuer. Please provide another token and try again.
With redirect uri: https://kavyasarabojub2c.b2clogin.com/kavyasarabojub2c.onmicrosoft.com/oauth2/authresp
So here the redirect Uris are correct and need to correct the metadata url :
Created an OpenId provider with meta data url having tenantId instead of organizations .
https://login.microsoftonline.com/<tenantId>/v2.0/.well-known/openid-configuration
Run the user flow with this Identity provider
Could login successfully and get the access token with endpoint
Note: make sure it has the policy included:
I have p=B2C_1_newSignupSignin
https://kavyasarabojub2c.b2clogin.com/kavyasarabojub2c.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1_newSignupSignin&client_id=1xxxxe2a5&nonce=defaultNonce&redirect_uri=https%3A%2F%2Fjwt.ms&scope=openid&response_type=id_token&prompt=login
Here the issuer is of V2 endpoint "iss": "https://kavyasarabojub2c.b2clogin.com/<tenantId>/v2.0/"
Reference : Web sign in with OpenID Connect - Azure Active Directory B2C | Microsoft Learn
Edit:

Response URI for Azure AD B2C returns 404, custom OpenID identity provider

We're implementing a custom identity provider for Azure AD B2C, using OpenID protocol option, as a generic OpenID Connect.
Everything works as expected until it's time to post the response back to Azure AD B2C using the redirect URI provided. I've found documentation regarding expected structure of this response URL, and what we see in the documentation is identical to what Azure AD B2C specifies when it issues the authentication sequence.
Configured values:
Response type: code
Response mode: form_post
User ID claim: sub
Display name claim: name
When the custom identity provider GETs or POSTs authentication response (code) back to https://REDACTED.b2clogin.com/REDACTED.onmicrosoft.com/oauth2/authresp, the Azure B2C returns 404.
Note that this is not 400, not 401, not 403, not 5xx. It is precisely 404 (not found), with a basic text (non-html) content saying resource not found. This response looks to me very much like a misconfigured API management layer on Azure side, hitting a wrong internal URL.
We're expecting that the URL https://REDACTED.b2clogin.com/REDACTED.onmicrosoft.com/oauth2/authresp actually works. It looks like what the expected Azure AD B2C response endpoint is from documentation, and it is also exactly what Azure AD B2C itself specifies when initiating the OpenID sequence with our custom identity provider web application.
So far we were unable to find the root cause, nor even any useful input beyond raw network request logs (case with Microsoft support was open since 2023-01-23). The last resort could be re-creating the B2C tenant, since this feature seems to work for other people, but that would require migration and significant down time on our end.
SOLUTION: The response to AD B2C authresp endpoint was missing 'nonce' claim (in the id_token payload), and 'state' parameter in the HTTP request. Both values are supplied by AD B2C when initiating authorization. As soon as custom identity provider started properly adding those two values, error 404 went away.
Response should include supplied nonce as a claim inside the id_token payload, and supplied state as HTTP request parameter or query string
https://openid.net/specs/openid-connect-basic-1_0.html
I had the same issue (a 404 error as a result of the /authresp POST from my custom OIDC IdP back to Azure AD B2C using the redirect URI Azure AD B2C had just provided as a query parameter on the /authorize request to my IdP: redirect_uri=https://mytenant.b2login.com/mytenant.onmicrosoft.com/oauth2/authresp
In my case (using an implicit flow), it was about properly handling the "nonce" query parameter on the inbound /authorize request (from Azure AD B2C to my IdP) by ensuring the generated id_token it returned included the nonce as a claim.
In your case (using an authorization code flow...and assuming you also return an id_token based on the "sub" and "name" claims you're returning), your /token endpoint needs to include the nonce inside the id_token...so propagate the nonce (and state) as query parameters along to your /token endpoint via the /authorize to /token redirect method you use.
If a federated IdP doesn't include the nonce as a claim inside the id_token payload that it returns, Azure AD B2C will return a 404 error from the /authresp request.
I don't know why Microsoft chose to return a 404 instead of a more informative "nonce invalid" error message, or at least, a 400 error...perhaps it's for the same security reason a login form doesn't precisely tell you when your password is invalid.
In the OpenID Connect specification, the nonce description (under IDToken) states (bolding is my doing):
String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token. If present in the ID Token, Clients MUST verify that the nonce Claim Value is equal to the value of the nonce parameter sent in the Authentication Request. If present in the Authentication Request, Authorization Servers MUST include a nonce Claim in the ID Token with the Claim Value being the nonce value sent in the Authentication Request. Authorization Servers SHOULD perform no other processing on nonce values used. The nonce value is a case sensitive string.
Although the spec indicates a nonce is optional, Microsoft is following best practices by supplying one...and since Azure AD B2C (as the Authorization Server) gets the id_token from the IdP, it requires a federated OIDC IdP to play by the same rule.
In case this helps others, my custom IdP's /.well-known/openid-configuration endpoint returns:
{
"authorization_endpoint": "https://myidp.azurewebsites.net/oauth2/authorize",
"authorization_response_iss_parameter_supported": true,
"claims_parameter_supported": false,
"claims_supported": [
"aud",
"idp",
"iss",
"iat",
"exp",
"nonce",
"s-hash",
"sid",
"sub",
"auth_time",
"email",
"family_name",
"given_name",
"locale",
"name",
"updated_at",
"user_id"
],
"claim_types_supported": ["normal"],
"grant_types_supported": ["implicit"],
"id_token_signing_alg_values_supported": ["RS256"],
"issuer": "https://myidp.azurewebsites.net",
"jwks_uri": "https://myidp.azurewebsites.net/oauth2/jwks",
"response_modes_supported": ["form_post"],
"response_types_supported": ["id_token"],
"scopes_supported": ["openid"]
}
(Yes, my IdP runs on an Azure App server...but, "myidp" isn't my real tenant name.)
p.s. Currently, my IdP is used exclusively in a federation with AzureAD B2C (which acts as the Authorization Server for my client application via the MSAL library), so my IdP simply supports just an implicit flow and three endpoints (/.well-known/openid-configuration, /jwks and /authorize). If it were a general purpose IdP, or allowed direct client requests, it would support other flows (e.g. an authorization code flow), additional scopes (beyond "openid"...e.g. "profile") and additional endpoints (e.g. /token and /userinfo). However, regardless of flow, as long as an id_token is returned, it needs to include the nonce in its payload.
To troubleshoot the issue, I would recommend the following steps:
Verify that the redirect URI you are using is correct and matches
the one specified by Azure AD B2C.
Check that the response type and response mode specified in your
custom identity provider match the values expected by Azure AD B2C.
Verify that the claims you are sending in the response (e.g. "sub"
and "name") match the expected format and values for Azure AD B2C.
Check the network request logs for any additional information that
might help identify the issue.
If possible, try to isolate the issue by testing the authentication
flow with a minimal configuration to determine if the problem is
with your custom identity provider or with Azure AD B2C.
If the issue persists after trying these steps, you may want to consider reaching out to Microsoft support for further assistance.
I tried to reproduce the scenario in my environment:
Make sure the endpoint to which I requested the authorization url
It includes policy and with
redirect URI= https://kavyasarabojub2c.b2clogin.com/kavyasarabojub2c.onmicrosoft.com/oauth2/authresp
User Flow is of SignupSignin and not just Signin
Make sure to include all the required api permissions , importantly make sure to include openid , profile
I Configure idp such that , userId is mapped to oid.
The authorization url must have the policy included .
Here I have B2C_1_SignupSignin policy set for the User flow.
redirect URI= https://kavyasarabojub2c.b2clogin.com/kavyasarabojub2c.onmicrosoft.com/oauth2/authresp
Auth url:
https://kavyasarabojub2c.b2clogin.com/kavyasarabojub2c.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1_newSignupSignin&client_id=xxx&nonce=defaultNonce&redirect_uri=https%3A%2F%2Fxxxb2c.b2clogin.com%2Fxxxb2c.onmicrosoft.com%2Foauth2%2Fauthresp&scope=openid&response_type=id_token&prompt=login
When profile scope is not given I got bad request
But when openid and profile along with Directory.Read.All api permissions are included, the request run successfully.
Note: metadata url must be : https://login.microsoftonline.com/<tenantId>/v2.0/.well-known/openid-configuration
Successfully logged in and got the token containing idp_access_token
Identity provider access token , decoded and got the user claims:

Azure AD B2C Custom Policy with external identity provider Error AADB2C90289

I have successfully configured an external identity provider using Azure AD B2C Custom policy. The authorize endpoint is passed correct acr_values too. As I launch the authorize endpoint, I am taken to the login screen from identity provider. As soon as I enter my credentials and hit 'Login',I expect the authentication response to be redirected to my B2C /auth/resp URL (https://<>.b2clogin.com/<>.onmicrosoft.com/oauth2/authresp), configured with the identity provider.
However, I end up getting an exception as below -
AADB2C90289: We encountered an error connecting to the identity provider. Please try again later.
Correlation ID: ef54294f-2a9d-4e18-bc03-511bcc713cde
Timestamp: 2022-10-10 04:04:09Z
AADB2C90289: We encountered an error connecting to the identity provider. Please try again later.
Correlation ID: 42dc0316-16d5-4f5b-9552-6cc4d2f3e233
Timestamp: 2022-10-10 09:38:51Z
I have also tried verifying the client_id and client_secret being used and that seems to be fine. Moreover, logs on the identity provider side mention that the request was successful.
Awaiting quick responses, as this blocks my application completely.
Application Insights details -
Exception Message:An internal error has occurred., CorrelationID:145303ec-b8e8-4fc1-bd5d-6649bd1fb77f
I tried to reproduce the same in my environment:
This error , AADB2C90289: We encountered an error “” connecting to the identity provider. Please try again later. occurred ,
when I haven’t given the clientSecret of the app correctly in the azure ad b2c.
I kept it to generate.
Later I manually changed the policy keys and gave the application client secret in the key value.
In your external Identity provider technical profile, make sure to -provide the clientId of that particular Identity provider
Ex:
<TechnicalProfile Id="Facebook-OAUTH">
<Metadata>
<!Below replace clientId with the externalIdentity provider App/ClientId "-->
<Item Key="client_id">XXX0000XXX</Item>
....

SecurityTokenInvalidSignatureException: IDX10511

Looking for some answer. First time using Azure AD for authentication on ASP.Net Core and we have registered the app on azure for both my local and Dev-Server. Its working running on my laptop but after deploying to Dev server and changing the Client ID Value, it keeps giving me this error
*SecurityTokenInvalidSignatureException: IDX10511: Signature validation failed. Keys tried: 'System.Text.StringBuilder'.
kid: 'System.String'.
Exceptions caught:
'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.
System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(string token, TokenValidationParameters validationParameters)
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()*
Thank you in advance.
Danny
Thank you #User 45323833 posting your suggestion as an answer to help other community members.
" Solution from Microsoft: This problem caused due to your app registration:
May you have defined a scope from Graph API: User.Read User.ReadBasic.All Mail.Read
If a scope will be set from Graph API, the token can just be validated from Graph!
You can see that in jwt.io. If the aud is like "00000003-0000-0000-c000-000000000000" the token is from Graph.
To solve the problem please follow the below steps :
To protect our own custom API, you have to register an application to represent it on Azure AD and obtain an access_token/id_token for it.
Section - Expose an API: Create a new scope: name = access_as_user
Section - API permissions: Add a new permission for your registered application and your scope access_as_user
Section - Manifest: Change entry "accessTokenAcceptedVersion" from null to 2
Check the new token from azure with jwt.io. If the aud is equal the registered application id the token can be successfully validated."
For more information please refer this GitHub issue IDX10511: Signature validation failed. Keys tried: & Microsoft Documentation: Azure AD authentication with ASP.Net core web application

Using Quarkus OpenId Connect and Azure b2c

I'm building a backend-service that provides an API using Quarkus and I need to validate the incoming requests.
By default, quarkus uses keycload, but I want to validate with azure b2c.
At the moment I have the following configs:
quarkus.oidc.auth-server-url=https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/oauth2/v2.0/authorize?p={policy}
quarkus.oidc.application.application-type=service
quarkus.http.auth.permission.authenticated.paths=/hello/*
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.log.category."io.quarkus.oidc".level= DEBUG
And as an example:
#Path("/hello")
public class GreetingResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
#RolesAllowed("test")
public String hello() {
return "Hello RESTEasy";
}
But Quarkus keeps throwing the same error:
OIDC server is not available at the 'https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/oauth2/v2.0/authorize?p={policy}'
Am I doing something wrong?
Thanks in advance!
Policy name for Azure AD B2C, format is like
quarkus.oidc.auth-server-url=https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy-name>/oauth2/v2.0/authorize
(or)
quarkus.oidc.auth-server-url=https://<tenant-name>.b2clogin.com/<tenant-id> /<policy-name>/oauth2/v2.0/authorize
The code in your Azure AD B2C-enabled applications and APIs may refer
to login.microsoftonline.com in several places. For example, your code
might have references to user flows and token endpoints. Update the
following to instead reference your-tenant-name.b2clogin.com:
Authorization endpoint
Token endpoint
Token issuer
Please do check this MS docs for more information on the same.
2.
OIDC service application needs to know OpenId Connect provider’s token,
By default they are discovered by adding a /.well-known/openid-configuration path to the configured quarkus.oidc.auth-server-url.
Ex: https://{tenant-name}.b2clogin.com/{tenant-id}/.well-known/openid-configuration?p={policy-name}
By default, the iss claim value is compared to the issuer property which may have been discovered in the well-known provider configuration. But if quarkus.oidc.token.issuer property is set then the iss claim value is compared to it instead.
References:
quarkus/issues
security-openid-connect

Resources