Issue with Azure AD B2C with an Identity Provider and PKCE - identityserver4

I have set up a B2C identity provider pointing to the online test version of IdentityServer4:
https://demo.identityserver.io
My app registration is for a SPA application.
My user policy is a standard SUSI one.
Using the "Run now" option, the following parameters are sent:
p: B2C_1_SUSI_B2C
client_id: 5e58...620a
nonce: defaultNonce
redirect_uri: https://jwt.ms
scope: openid
response_type: code
prompt: login
code_challenge_method: S256
code_challenge: D9pGhYDch4f8F3V0MsDvaEQWH3-ssqucs3ixxTAgX6k
This contains the PKCE parameters as expected.
I get the B2C login screen and click the IdentityServer4 button.
The following parameters are sent to IdentityServer4:
client_id: interactive.public
redirect_uri: https://tenant.b2clogin.com/tenant.onmicrosoft.com/oauth2/authresp
response_type: code
scope: openid
response_mode: form_post
nonce: HZ0avacgvKw5Jyp6W4k1Tw==
ui_locales: en-US
state: StateProperties=eyJTSUQiOiJ4....
Notice that there are no longer any PKCE parameters.
IdentityServer4 responds:
Error
Sorry, there was an error : invalid_request
code challenge required
How do you get the PKCE parameters to be forwarded?

This is not possible right now. There is also almost no value to use PKCE here as it is a confidential client flow.

Related

Azure Authentication - Access Token returning wrong AUD(00000003-0000-0000-c000-000000000000)

I'm trying to authenticate with API Management in Azure through OAuth. I've set up that piece fine.
However from the response, the aud(00000003-0000-0000-c000-000000000000) is invalid from the access token.
Any suggestions/ideas to get the accurate aud in access_token.
I tried to reproduce the same in my environment and got the results like below:
I generated the access token with the same aud as you and got the validation error:
I agree with juunas, To authenticate with API Management in Azure through OAuth, make sure to pass the scope while generating the access token.
I created an Azure AD Application, exposed an API and added scope like below:
Added API permissions like below:
To resolve the error, make sure to pass scope as api://AppID/.default.
https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
client_id:ClientID
client_secret:ClientSecret
scope:api://ee1782a6-a994-4013-a396-XXXXX/.default
grant_type:client_credentials
A valid access token to access APIM will be generated like below:
To pass the particular scope from react app using MSAL you can make refer the below sample code:
auth: {
authority: "https://login.microsoftonline.com/common",
clientId: "ClientID",
postLogoutRedirectUri: RedirectURI
redirectUri: RedirectURI
validateAuthority: true,
navigateToLoginRequestUrl: true,
},
cache:
{ cacheLocation: 'sessionStorage',
storeAuthStateInCookie: true,
},
},
{
scopes: ['api://clientid/.default']
},
LoginType.Redirect
References:
OAuth 2.0 Authorisation with the Client Credentials Flow on Azure API Management by Paco de la Cruz
Connect React App with Azure AD using react msal by Ray
You have mistaken the values.
TL;DR: ignore "access token", obtain and read "id token" and verify that "aud" field is your client ID.
First you might obtain a single-use access code (likely something like 0.ABC). Optionally you could fetch open id token. "scope" must include "openid"
Then you can fetch actual open id token using the single-use code. "scope" must be "openid" again. Response might include:
access token - which can be anything including random number of characters, string, your full details or an JWT; I believe that Microsoft returns JWT which is meant to the "00000003-0000-0000-c000-000000000000" audience (meaning "only 00000003-0000-0000-c000-000000000000 can use it - ignore if you are NOT the one")
id token - which is an JWT and should contain your application ID (client ID) in the "aud" field
Always check the "aud" as this says who is the token created for. If it is not you - the token is not for you.

Several Audiences in JWT token to authenticate with azure AD

Requirements
I want to authenticate against Azure AD, (but later deployments can authenticate against any openID connect server)
I am using oidc-client-ts (I don't want to use anything else as I want to be able to authenticate against any Oidc server)
I am using code flow (not really relevant in this question)
I want my SPA to get a JWT token that permits to make graphApi calls (to get the profile of the user)
And of course I want my SPA to access my API server
This means the JWT token must be accepted by 2 audiences: GraphAPI, my API server
First attempt
Here are the settings I am giving to my UserManager:
const oidcSetups = {
authority: buildUrl(config.oAuthAuthority, config),
automaticSilentRenew: false,
client_id: config.oAuthClientId,
loadUserInfo: true,
redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`,
response_type: 'code',
scope: 'openid profile email'
};
The token given by azure ad permits me to get the profile (make a graphAPI call) because it has the audience claim set to target GraphAPI, but it doesn't have the audience claim for my API serveur.
Second attempt
Then, I tried this setting (the change is in the scope):
const oidcSetups = {
authority: buildUrl(config.oAuthAuthority, config),
automaticSilentRenew: false,
client_id: config.oAuthClientId,
loadUserInfo: true,
redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`,
response_type: 'code',
scope: 'openid profile email api://mycompany.pms/mycompany.api.read'
};
Then my JWT token has indeed the audience claim that is realated to api://mycompany.pms/mycompany.api.read. So this is what I want, except that GraphAPI refuses requests as it doesn't have the audience claim that corresponds to GraphAPI.
Question
How can I manage to get a JWT token that permits me to be accepted by several targets/audiences?
As I believe it is not possible to issue a token that target several audiences,what is the way for to access 2 different audiences with the user authenticating only once?
I struggled with this a couple of years ago and wrote this blog post. Microsoft use resource indicators for their own APIs, so you need to handle the MS APIs differently to your own custom APIs. This is the real issue here I think, rather than audience configuration.
Your SPA scopes look fine, and standards based, but I think you'll need to get Graph data via one of your APIs. This requires a different access token, which an API can retrieve via user assertions (on-behalf-of flow), and use of a client secret.

InteractionRequiredAuthError: invalid_grant: AADSTS50076

Error message: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access 'bxxx-xxxx-xxxxa'.
I am getting this error intermittently, while accessing token with auth code.
Token endpoint fails with error code 400.
Request body in browser contains:
POST: https://login.microsoftonline.com/tenantID/oauth2/v2.0/token
clientId,
scope - xxxxxxxx/.default openid profile offline_access
grant_type: authorization_code
code
redirect_uri
and here is MSAL configuration: (we are using react-msal 1.4.3)
const msalConfig = {
auth: {
clientId: env?.ClientId,
authority: env?.Authority,
redirectUri: env?.RedirectUri,
postLogoutRedirectUri: env?.PostLogoutRedirectUri,
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
},
scopes: [env?.AuthScope],
}
Please let me know if anyone has encounter this issue before and found any solution for it.
• It is because your administrator has enabled the security defaults setting in ‘Manage security defaults’ section in Azure AD tenant properties as shown below in the snapshot. When you enable this option, Azure AD mandates all users to register for Azure AD multi-factor authentication, requires the same for administrators and enforces it, blocks legacy authentication protocols, and protects privileged activities like access to the Azure portal.
Thus, if you are assigned a role of ‘Administrator’ of any sort, i.e., Global, Authentication, Application, Billing, Exchange, etc., then your ID would be required to do multi-factor authentication. Also, please ensure that you are not using any older protocol and legacy authentication since those doesn’t have access to multi-factor authentication.
As a result, this would help in resolving the issue and the subsequent error that you are facing. For more information, kindly refer to the below links given: -
https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults
https://learn.microsoft.com/en-us/answers/questions/494959/aadsts50076-ue-to-a-configuration-change-made-by-y.html

Pass custom HTTP header to IdentityServer 4 from oidc-client-js

I am in the process of setting up a solution with an ASP.NET Core WebApi, a Javascript client (with oidc-client-js) and an IdentityServer4 with Identity.
I have followed different tutorials and guides and have come to a solution that works well.
When accessing the JS client while not authenticated, I am redirected to the IdentityServer, where I can successfully log in and am redirected back to the JS client with my bearer token, which I then use to consume the API.
The system will have to support multiple "tenants", all sharing the same DB though.
The idea is to access the JS client with a tenant key in the URL and pass it on:
www.mydomain.com/{tenantKey}/someSubPage
I would like to read tenantKey and pass it IdentityServer using a custom HTTP header like X-My-Tenant-Key. IdentityServer should then include this key in the authorization process.
I have checked oidc-client-js' GitHub page and done some further research, however I was not able to find out how this could work.
The alternative would be to include the key in IdentityServer's URL and apply some MVC routing magic, or to somehow do some dirty stuff with the redirect_uri.
Before trying any of this, though, I wanted to see if I might be missing something here.
This is how my JS client prototype handles it right now:
// Setup
var config = {
authority: "http://localhost:50000",
client_id: "myClient",
redirect_uri: "http://localhost:65000/callback.html",
response_type: "id_token token",
scope: "openid profile email myApi",
post_logout_redirect_uri: "http://localhost:65000/index.html",
};
var mgr = new Oidc.UserManager(config);
...
// Signing in
mgr.signinRedirect();
Don't know if this is what you are looking for, but you can pass the Tenant Key as query parameter through "acr_values" from your client to Identity Server(Authorization Server). This is meant for situation like yours. You need to add acr_values to your client :
config = {
authority: "http://localhost:50000",
client_id: "myClient",
redirect_uri: "http://localhost:65000/callback.html",
response_type: "id_token token",
scope: "openid profile email myApi",
post_logout_redirect_uri: "http://localhost:65000/index.html",
acr_values : "tenant:your_tenant" };
Then you can access the values in your Authorization Server through Authorization Context for example :
string tenant = context.Tenant;
You can read the docs, one of its use is exactly for passing tenant information.

Azure AD B2C. ROPC flow error The application associated with client id has no registered redirect URIs

The application associated with client id 09ac92da-a796-4cd9-973b-c97756____ has no registered redirect URIs
Description
I followed the steps described in https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc?tabs=applications.
When attempting to obtain the token in Postman using ROPC I'm getting
{
"error": "invalid_request",
"error_description": "AADB2C90007: The application associated with client id '09ac92da-a796-4cd9-973b-c97756____' has no registered redirect URIs.\r\nCorrelation ID: e85003c3-cfd5-43ad-a74b-efa5c1ea6525\r\nTimestamp: 2019-12-06 19:47:42Z\r\n"
}
I should not be asked for a redirect URIs.
My POST is as follows:
URL: ''https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/v2.0/token?p=B2C_1_ROPC_Auth"
username: some_username_of_a_user
password: its-password
grant_type: password
scope: openid offline_access 09ac92da-a796-4cd9-973b-c97756____
client_id: 09ac92da-a796-4cd9-973b-c97756____
response-type: token id_token
I didn't reproduce your issue by following this document. Here are the main steps for your reference.
1.Create a resource owner user flow
2.Register an application(It is an application under Azure AD B2C, not Azure AD)
3.Test the user flow
This error generally occurs because you still need to configure some application claims in the b2c directory user flow to allow complete access to the application.
You need to make sure that the right versions of the authentication are in the reply url (likely extension v2.0) and that the reply URL is configured in the application and in the code.
Please look to the documentation for the reply URL schema that you would need to follow: https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=applications#register-a-web-application
If you still run into this issue let me know and I can reach out to the correct product team contacts, as sometimes this can happen due to breaking changes on our end.

Resources