If you (like me) were hoping to “easily” create a Blazor application that connects to a generic OIDC identity-provider using the Microsoft.AspNetCore.Components.WebAssembly.Authentication library, while also supporting connections to Azure Active Directory (AAD) this way, you’ll be disappointed.
The idea is simple, AAD does support OIDC and therefore now why shouldn’t a generic OIDC client be able to connect to AAD as well. Unfortunately the hurdles are more than you would like to overcome.
While the Microsoft.Authentication.WebAssembly.Msal library for AAD is an extension of the underlying Microsoft.AspNetCore.Components.WebAssembly.Authentication library, it does a lot more than just boilerplate configuration of the underlying generic OIDC.
The basic difference can be found, for example, in the “interop” part with the underlying oidc-client JavaScript module.
AuthenticationService.tsinMicrosoft.AspNetCore.Components.WebAssembly.Authentication,AuthenticationService.tsinMicrosoft.Authentication.WebAssembly.Msal.
This is manifested for example when retrieving access-tokens. The MSAL version “fixes” the AAD specificity that when querying atokenendpoint does not always return an access-token with all required scopes (the details are for a broader discussion, but e.g. you don’t get a token that hasUser.Readscope in it along with the custom-scope of your API, etc.).
The base library uses the “caching” of tokens in the oidc-client UserManager and relies on the assumption “If token-endpoint returned an access-token, then that token has all the required scopes in it.” (i.e., it stores the required scopes for the retrieved token, and then returns the already retrieved token the next time the same scopes are requested).
The “fixed” MSAL library knows this shortcoming of the underlying oidc-client and knows that while it claims to have a token for some set of scopes, the access-token may not actually have those scopes. Therefore, it “turns off” caching at this level and always gets the token again.