microsoft-identity-web
microsoft-identity-web copied to clipboard
[Bug] When using Microsoft.Identity.Web.Owin in NET48 MVC application Graph Integration does not work
Microsoft.Identity.Web Library
Microsoft.Identity.Web.OWIN
Microsoft.Identity.Web version
2.15.1
Web app
Sign-in users and call web APIs
Web API
Not Applicable
Token cache serialization
Not Applicable
Description
When using the Microsoft.Identity.Web.Owin to setup openident auth integration for an NET 4.8 MVC application. The AddMicrosoftGraph()
integration does not work.
What happens is that the auth token resolved during the AuthorizationCodeReceived
can never be properly resolved by the application when using the GetGraphServiceClient()
controller extension.
This is because the TokenAquisition infrastructure uses the BootStrapToken as made available on the ClaimsPrincipal (See the GetBootstrapToken
extension method in Microsoft.Identity.Web.PrincipalExtensionsForSecurityTokens.cs
). This token is used to build the CCA and perform a AcquireTokenOnBehalfOf
call. Because the security token is null, no auth token is ever resolved. Thus causing the graphsdk client to fail.
I don't know if this is due to some specifics in my NET48 MVC application, or if this is general NET48 MVC issue. But this Bootstrap token was never set on the ClaimsPrincipal. Causing errors when calling the GRAPH Api when using the GraphServiceClient.
The solution is to adjust the OpenIdAuthenticationOptions.TokenValidationParameters and force the SaveSigninToken to true.
The Bug is that this isn't done by default in the Microsoft.Identity.Web library.
Addendum:
Besides the above i have a question:
When the library is already aquiring a token in the AuthorizationCodeReceived
callback. it seems strange to me that the tokenaquisition layer is using the security token to aquire a new Token when the graphclientprovider is called. I would have expected that it would use the msalaccountid or something to aquire the token from the cached CCA (and thus getting it from tokencache) via a call to AcquireTokenSIlent.
For me resolving and then using the GraphServiceClient always results in a call to this function:
https://github.com/AzureAD/microsoft-identity-web/blob/efd1dec1f49cac8a7e7e4c821478c1af95cbc758/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs#L700
Which uses this method with the bootstraptoken. And it just seems wrong. Context: I have build my own token aquisition integration in the past, on top of the openidconnect libraries to do exactly what the tokenaquisition layer in microsoft.identity.web attempts to do. I never had to use the Bootstrap token. I was evaluating this library to see if we can get rid of our own stuff.
Reproduction steps
Init net 48 MVC application with the Owin Infrastructure using the OwinStartup attribute. Init the identity web bits using the code snippet supplied below.
After authenticating try to call the graph api using the GetGraphServiceClient
controller extension.
Get error.
Error message
No Account or login hint was passed to the AcquireTokenSilent call
Id Web logs
No response
Relevant code snippets
var factory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>(configSection:"AzureAd");
app.AddMicrosoftIdentityWebApp(factory, null, updateOptions:
openIdOptions =>
{
openIdOptions.CookieManager = new SystemWebCookieManager();
openIdOptions.TokenValidationParameters.SaveSigninToken = true;
})
.UseStageMarker(PipelineStage.Authenticate);
factory.Services
.AddMicrosoftGraph();
factory.Build();
Regression
No response
Expected behavior
That the bootstrap token / security token is acquired by default when using the library in a netframework setting.
Alternatively that the docs regarding usage in NET framework reflect this issue.