Using Quarkus OpenId Connect and Azure b2c - azure

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

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:

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

Error getting SAML Metadata for Azure AD B2C Policy - AADB2C90022

Setting up a custom policy in Azure AD B2C to connect to an ADFS Identity Provider. This requires a SAML metadata endpoint as specified in the documentation at the link below.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-custom-setup-adfs2016-idp#configure-an-adfs-relying-party-trust
The error being encountered is:
AADB2C90022: Unable to return metadata for the policy [my-policy] in tenant [my-tenant].onmicrosoft.com.
and is being encountered when I go to the endpoint:
https://login.microsoftonline.com/te/[my-tenant].onmicrosoft.com/[my-policy]/samlp/metadata?idptp=[my-technical-profile]
I have tried making the request from the b2clogin.com endpoint with the same result as above.
E.g. https://[my-tenant].b2clogin.com/te/[my-tenant].onmicrosoft.com/[my-policy]/samlp/metadata?idptp=[my-technical-profile]
I have also tried using my tenantId GUID in place of [my-tenant].onmicrosoft.com which resulted in the exact same result.
E.g. https://login.microsoftonline.com/te/[my-tenant-id]/[my-policy]/samlp/metadata?idptp=[my-technical-profile]
Re-visit the process by which you created the certificate, uploaded it to your 'Policy Keys' and referenced it in your custom policy files.
My scenario was similar, I had the same error and no output via Application Insights / Journey Recorder.
I had tried to avoid using 'makecert.exe' and instead used another SSC generation tool. This simply did not work, I think because the private key was not being incorporated in the certificate file.
This guide has been invaluable, see also this test facility

Azure AAD - The audience is invalid

I have create a webapi secured with azure active directory. I need to test this now and trying to use fiddler with an authorization header. I am trying to generate the token with below code.
Target obj = (Target)cmbTarget.SelectedItem;
AuthenticationResult authenticationResult;
string aadInstance = obj.AADInstance; // "https://login.windows.net/{0}";
string tenant = obj.Tenant; //"rudderless.onmicrosoft.com";
string apiResourceId = obj.ApiResourceId; //"15b4ac7f-23a8-4958-96a5-64159254690d";
string clientId = obj.ClientId; // "47cdc6c3-226a-4c38-b08e-055be8409056";
Uri redirectUri = new Uri(obj.RedirectUri); //new Uri("http://nativeclient");
string authority = string.Format(aadInstance, tenant);
authContext = new AuthenticationContext(authority);
authenticationResult = this.authContext.AcquireToken(apiResourceId,
clientId, redirectUri, PromptBehavior.Always);
txtToken.Text = authenticationResult.AccessToken;
Clipboard.SetText($"Bearer {txtToken.Text}");
I get the token generated successfully and when I am using the token to call the webapi it throwing 401 with message
WWW-Authenticate: Bearer error="invalid_token", error_description="The
audience is invalid"
I think it is important to revisit the different steps of authentication, and hopefully through the discussion you will be able to solve the issue you are having.
When a client is trying to get an access token to a resource, it needs to specify to AAD which resource it wants to get a token for. A client may be configured to call multiple resources, all with different configurations, so it is an expectation that the resource is always specified in an Access Token Request.
The resource can either be an App ID GUID for the Resource, or a valid App ID URI which is registered on the Resource. AAD should be able to uniquely identify which resource you are trying to reach based on the value you provide. However, note that if you use an App ID GUID, you will get a token from AAD where the Audience claim is the App ID GUID. Alternatively, if you use an App ID URI, you will see that URI as the audience claim in the token.
In both situations, you will get a token for the 'same' resource, but the claim in the token will appear differently. Additionally, it may be possible that a single application resource may have multiple App ID URIs registered on their app. Depending on which one you use in the authentication request, you will get a different audience claim in the token which matches the resource parameter you passed in.
Finally, once you get the token, you send it over to the Resource API who will validate the token for a number of things, such as: the Client ID Claim, the Scopes/Roles Claims, the authentication method ('acr' claim), and definitely that the audience claim matches what they expect!
This means that the Resource API ultimately needs to say "I accept < App ID GUID > as a valid Audience Claim"... or "I accept < App ID URI > as a valid Audience Claim". This kind of logic may be built into the library you are using (like OWIN), but you need to make sure that on your API side, you have it configured correctly for the Audiences you expect. You could, if you wanted, make it so that your API does not check the Audience claim at all! All the claims in the token are plaintext, and thus you could really do whatever you want, but you would not have a very secure API in that situation :]
End of the day, my hunch is that this error is coming from your own API, and it is happening because you have not configured your app to accept an Audience claim which matches your Resource's App ID GUID (which it looks like what you are passing when you are getting a token based on your code sample).
I hope this solves your issue!
Problem
After implementing the instructions found in this Protected web API: Code configuration article, I received an error message similar to the OP's:
WWW-Authenticate: Bearer error="invalid_token", error_description="The
audience is invalid"
The problem turned out to be my AzureAd > ClientId setting in my appsettings.json file.
Solution
I updated the appsettings.json file of my ASP.NET Core Web API app so that the ClientId setting used the "Application ID URI" found in portal.Azure.com under my App Registriation > "Expose An API" section.
The section in appsettings.json looks similar to this:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "XXXXXXXX-XXXXX-XXXXX-XXXXX-XXXXXXXXXX",
// ClientId = Portal.Azure.com > App Registration > Expose an API > "Application ID URI"
"ClientId": "api://XXXXX-XXXXXX-XXXXX-XXXX-XXXXXXXXX"
}
Important note
"aud" value that is being generated for JWT token by azure is also controlled by "accessTokenAcceptedVersion" property in AD application manifest.
This property defines a version of the access token that will be generated (MS docs about accessTokenAcceptedVersion).
Possible results for its values:
null or 1 - "api://" prepended to GUID
2 - "api://" is not added, so there should be GUID only
I had the same issue. Thought of sharing it. I have change the Web Api Audience to the ClientId of the Web App. After this it works.
The Microsoft references show the following example:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Client_id-of-web-api-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]",
"TenantId": "common",
"Audience": "custom App ID URI for your web API"
},
// more lines
}
Can also be that your app/lib is using a newer version of the api.
If accessTokenAcceptedVersion is null in the manifest of your app ms defaults to v1.
Check your jwt token in http://jwt.io
If you get this - check your JWT Token. If ISS isn't like this
"iss": "https://login.microsoftonline.com/[yadyada]/v2.0",
then most likely you're using another version (like version 1 which is default). Check the manifest of your azure ad app:
Below value is probably null or one, should be two:
"accessTokenAcceptedVersion": 2,
I had the same issue. I was using the client's Resource ID as the parameter for AcquireToken when I should have used the server's Resource ID.
It works when I use the correct Resource ID.
I got the same error. It was because I was using a custom domain, so my API ID URL wasn't api://{client-id}.
The solution is to set the Audience setting on your appsettings.json, just like mentioned in the Microsoft Wiki:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "XXXXXXXX-XXXXX-XXXXX-XXXXX-XXXXXXXXXX",
"ClientId" : "XXXXXXXX-XXXXX-XXXXX-XXXXX-XXXXXXXXXX",
// Audience = Portal.Azure.com > App Registration > Expose an API > "Application ID URI"
"Audience": "Application ID URI"
}
While calling api for implementing service principle through App registration in active directory.
I got this error while calling api-GET {vaultBaseUrl}/secrets/{secret-name}/{secret-version}?api-version=7.0 with bearer key to get key vault secret value.
As part of fix, to get bearer value, Apart from passing clientid, client secret, grant_type,I added resource key with value https://vault.azure.net as part of request body of api call for https://login.microsoftonline.com/{ActiveDirectoryId}/oauth2/token.
This might help someone: I've encountered this error because the MS Graph User.Read permission was missing on the SharePoint Online Client Extensibility Web Application Principal. Out of the box, this app reg already has the User.Read permission, but I had removed that one because (for an earlier project) I already used User.Read.All, thinking that it included User.Read. However, User.Read is used for sign-in purposes while User.Read.All is not. When I restored User.Read, my problem was solved.
Quite the unintuitive solution.

How to configure permissions for the Azure AD authentication v2.0

I have set up a new web app to be able to use the Oauth2 V2 authorization endpoint. I defined the app in https://apps.dev.microsoft.com/
If I want to obtain a new authorization token, following instructions in
https://blogs.msdn.microsoft.com/richard_dizeregas_blog/2015/09/04/working-with-the-converged-azure-ad-v2-app-model/
I get the following error on the login page:
Sorry, but we’re having trouble signing you in.
We received a bad request.
Additional technical information:
Correlation ID: eb9c2331-32bd-45a9-90d1-e9105f0bfa87
Timestamp: 2016-05-22 18:10:48Z
AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://graph.microsoft.com/Calendar.Read is not valid.
The scope is taken from an example in :
https://github.com/Azure/azure-content/blob/master/articles/active-directory/active-directory-v2-scopes.md
So I imagine it is a valid scope.
In v1 of the OAuth2 protocol, it was necessary to configure access to APIs in the Azure AD of my tenant, prior to using them. So I attempted to do so for the new application.
Attempting to do so, the Azure application management reports an error:
{
"message":"This request has a value that is not valid.",
"ErrorMessage":"This request has a value that is not valid.",
"httpStatusCode":"InternalServerError","operationTrackingId":null,"stackTrace":null,"Padding":null
}
What is missing to be able to use the new authorization endpoint ?
The documentation contains a typo if states calendar.read. It must be calendars.read:
private static string[] scopes = {
"https://graph.microsoft.com/calendars.readwrite"};
Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, additionalScopes, clientId, redirectUri, UserIdentifier.AnyUser, null);

Resources