-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] GetAuthenticationResultForUserAsync throws an exception when user is authenticated #2968
Comments
I am getting the same behavior. |
Are you not in this use case : https://github.com/AzureAD/microsoft-identity-web/wiki/Managing-incremental-consent-and-conditional-access ? |
@vincentlemordanttechso no, as I mentioned, doing the OBO works using the REST endpoint, when taking the access token returned. The problem seems to be within the library (unless I'm told otherwise), as the user doesn't seem to be saved in the cache. |
seems like I get it working. I continue investigating and will publish my sample app once done. |
Thanks @VladislavAntonyuk Unfortunately, this is not in a Blazor app. As per my description, this seems to be a cache problem. As the user is able to get an access token, but that access token doesn't seem to be stored in the cache and thus cannot be retrieved. @jmprieur any idea? |
@bgavrilMS can you please take a look at this cache issue? Thanks. |
@jennyf19 - we can have a look, but why is Id.Web calling |
I just updated to the latest release 3.1.0 and it is no longer giving me problems. |
@Norrch2 unfortunately, 3.1.0 still gives the same problem. |
I don't think this is related to in-memory caching. |
I cannot find the code shared here: string accessToken;
// ITokensAcquisition is scoped, so we need to create a new scope here as the handler is a singleton
using (var scope = _serviceProvider.CreateScope())
{
var a = scope.ServiceProvider.GetRequiredService<ITokenAcquisition>();
var x = await a.GetAuthenticationResultForUserAsync(_apiOptions.Scopes, user: context.User);
accessToken = x.AccessToken;
} but the token that was validated by the web API is not known by TokenAcquisition in this scope, because TokenAcquisition is, by default, as scoped service, so you are creating a new instance of token acquisition (the one above does not have the context of the request), which you don't want to do. You can either not create the scope above, or use TokenAcquisition as a singleton by calling one issue is here you should be using Also, we would advise that you just do Authorization should happen from the claims, not the body, as you have set up here because using the claims is secure because the token is validated. Closing, but feel free to respond here if you have questions. |
@DOMZE what are the differences in the environments? related to: |
@henrik-me it is the same user. Taking the access token and calling the endpoint for the OBO flow with the requested scope in Entra is not giving any consent error and goes through with the OBO returning an access token for the requested API/scopes. So I don't think this is an Entra problem as I went straight to the source to verify if really consent was necessary. So the differences I'm talking about are:
versus
What's concerning to me is the |
what is the difference in the environments? |
Ok, so I had a look at the code for the web site. And I managed to repro like this:
This is expected. The key is point 2 - I restarted the service which led to the deletion of the memory cache. ASP.NET core maintains cookies and remembers the user, but their access token is gone. The correct solution is to redirect the user back to the auth page. |
You could use some persisted cache or you could use session cache, see https://learn.microsoft.com/en-us/entra/msal/dotnet/how-to/token-cache-serialization?tabs=aspnetcore But you must handle this exception, because it can also occur for other reasons, such as the tenant admin adding an MFA policy. |
The problem occurs on the first try (the webserver is never restarted), i.e:
Same occurs in Incognito mode:
You mentioned using session cache, but as per @jennyf19's recommendation, ITokenAcquisition There's something that is failing in the MSAL cache when storing the tokens (post sign-in), thus the difference ( |
Do you have the |
I have connected with the customer and we have made some progress. Here's what's happening:
Note that at step 4 we made sure that a token is in the cache from step 3. I manually checked that an account exists in MSAL's cache with that exact ID. The CX tried this with their regular setup, which is ADFSv4 federated to AAD. And it is failing with Next steps:
|
Hi @DOMZE - I updated the sample and should be able to get a few more details out. YOu should:
Then send the logs over. |
@jmprieur @jennyf19 - I couldn't configure Id.Web to log MSAL pii messages. What am I doing wrong? https://github.com/dstamand-msft/demo-authnauthz/blob/main/src/Demo.App/appsettings.json |
Did you look at https://github.com/AzureAD/microsoft-identity-web/wiki/Logging ? |
I did. But all examples show how to set it via config. But this sample uses code, not config, and I couldn't figure out how to set it. That said, even in WebAppCallsGraph devapp I can see that the PII flag is always false once it reaches MSAL. |
Events need to be chained, Bogdan, otherwise you lose all benefit of using IdWeb. |
Ok, I have found the problem. The A solution for Id.Web is to use names like
Thoughts @jmprieur ? @DOMZE - to workaround this, could the CX configure Entra so that it doesn't add |
@DOMZE - while the team thinks about how to fix this, can you see on your end if custom claim named |
@bgavrilMS I did ask. Awaiting reply and see if we can test without that |
@bgavrilMS confirmed, removing the |
Ok, so there are
|
closing as won't fix. |
Let's re-open this as @DOMZE is working on it |
Microsoft.Identity.Web version and scenario
3.0.1
Web app calls web api.
Problem description (updated by @bgavrilMS for clarity)
In a typical web app calls web api scenario, Identity.Web always throws
MicrosoftIdentityWebChallengeUserException
with error codeuser_null
when callingTokenAcqusition
API. For some application registrations, but not for all.The issue only occurs when the ID Token is customized to have an additional claim named
uid
, via the app portal. For example:Root cause: Microsoft.Identity.Web tries to inject its own
uid
claim into the id token / ClaimsPrincipal (which it gets from client_info). This conflicts with the user'suid
claim and the user's claim wins. This breaks Microsoft.Identity.Web's ability to reference a user from MSAL's cache, causing theuser_null
error.Original Description
I'm having trouble with another user with the OBO flow using Microsoft.Identity.Web (MIW). The code works on my machine and in my environment (Azure). However, the exact same code does not work the other users' machine & environment. The log on the other users' environment confirms that the tokens are being saved in the cache (In Memory Cache).
I can confirm that the
ClaimsPrincipal
is properly populated in both environment (as shown when signing in).App Registrations have been verified on both end (mine and the other users). The token can be exchanged with the proper requested scope for the requested application using REST calls, thus not a problem with App Registrations. The admin consent has been granted and I am not using the ./default scope but rather requesting a specific scope i.e
api://<app_name>/scope_name
Enabling the logs for the library, I realize that in my environment the account is saved AND is retrieved when doing the OBO call using
ITokenAcquisition.GetAuthenticationResultForUserAsync
. In the other users' environment, this gives the error:The logs says that the account in the cache is not found (0 account in cache) and thus why this fails.
See logs below
Reproduction steps
PermissionActionAuthorizationHandler
fileError message
Microsoft.Identity.Web.MicrosoftIdentityWebChallengeUserException: IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent.
---> MSAL.NetCore.4.61.3.0.MsalUiRequiredException:
ErrorCode: user_null
Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
Id Web logs
Own environment:
Other users environment:
Relevant code snippets
Regression
No response
Expected behavior
Expected the access token to be in the cache for the other users
The text was updated successfully, but these errors were encountered: