TLDR: WebApi migrated from ADAL to MSAL does no longer work when called by another API with direct permissions. (Yet, it does work when using on behalf tokens.) Link to a minimal example at the bottom.
Recently I started to migrate some dotnet API’s from ADAL to MSAL. Some of these API’s are called directly from frontends others are used by other API’s. In the calls to the API’s there are the bearer tokens present in the headers, normal stuff. We use two types of tokens:
- User/on behalf of tokens and;
- Application tokens, tokens derived from the application identity.
The API’s make use of the current latest version of Microsoft.Identity.Web. In our case it does both the validation of the tokens and the creation of new tokens. We noticed that in the case of user/on behalf tokens, everything works as expected. However, for application tokens we are noticing some odd things. In this case we are noticing in particular that it does not pass a “RequireAuthenticatedUser” policy check (default dotnetcore 3.1) on the controllers.
Both tokens use the same audience and both tokens are derived from the same app registration in AD. So it does not feel like a configuration issue.
A workaround that doesn’t feel right: we noticed that if we override the “OnTokenValidated” that is set by Microsoft.Identity.Web, and only let it fire normally in the case of a user/on behalf of token, we experience no issues.
This finding is peculiar since it is the “OnTokenValidated” event that fires. The token has apparently been validated. The principal has an identity and a user which also has claims and has a “IsAuthenticated” flag that is set to true. But after the function chain that is present through the dependency injection something happens that makes the user invalid an removes the claims that where present through the token.
I have create a minimal example application that demonstrates the issue. See https://github.com/tychok/tokenissues, the only thing you will have to do is set “ClientId” and “Audience” in “appsettings.json” with your own id’s.
In this example apptokens do work due to some peculiar code in ” Startup.cs” from line 43 to 54. If that code is not present apptokens will receive a 401, while user tokens continue to work.
The questions are:
- Is there something wrong with our approach to the validation to the tokens?
- What can we do to make this work?
