问题
I’m writing a basic Blazor app following this blog post and I've struck difficulty with the /callback redirect in the actual Blazor application. The error I’m seeing is
OpenIdConnectProtocolException: Message contains error: 'invalid_grant', error_description: 'Invalid authorization code', error_uri: 'error_uri is null'
at the /callback URL.
If I check the logs, I can see there are three events happening at the Auth0 end:
- Successful login
- Authorization Code for Access Token
- Invalid authorization code
Each straight after the other. I can see those authorization codes do match between the “Success Exchange” and the “Failed Exchange” entries.
I can see Auth0 authentication has actually taken place, and if I browse to other pages in my app, I can see I have logged in successfully, but that initial callback to the /callback URL stops things in their tracks. Is there something missing in the middleware / Startup.cs code, or are there additional things to check for the Auth0 application settings?
For the avoidance of doubt, I've copied the blog post code exactly and can confirm the application does authenticate and log me in. Here's the code in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
services.AddSingleton<WeatherForecastService>();
services.AddSingleton<ClubInformationService>();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// Add authentication services
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("Auth0", options =>
{
// Set the authority to your Auth0 domain
options.Authority = $"https://{Configuration["Auth0:Domain"]}";
// Configure the Auth0 Client ID and Client Secret
options.ClientId = Configuration["Auth0:ClientId"];
options.ClientSecret = Configuration["Auth0:ClientSecret"];
// Set response type to code
options.ResponseType = "code";
// Configure the scope
options.Scope.Clear();
options.Scope.Add("openid");
// Set the callback path, so Auth0 will call back to http://localhost:3000/callback
// Also ensure that you have added the URL as an Allowed Callback URL in your Auth0 dashboard
options.CallbackPath = new PathString("/callback");
// Configure the Claims Issuer to be Auth0
options.ClaimsIssuer = "Auth0";
options.Events = new OpenIdConnectEvents
{
// handle the logout redirection
OnRedirectToIdentityProviderForSignOut = (context) =>
{
var logoutUri = $"https://{Configuration["Auth0:Domain"]}/v2/logout?client_id={Configuration["Auth0:ClientId"]}";
var postLogoutUri = context.Properties.RedirectUri;
if (!string.IsNullOrEmpty(postLogoutUri))
{
if (postLogoutUri.StartsWith("/"))
{
// transform to absolute
var request = context.Request;
postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
}
logoutUri += $"&returnTo={ Uri.EscapeDataString(postLogoutUri)}";
}
context.Response.Redirect(logoutUri);
context.HandleResponse();
return Task.CompletedTask;
} //... etc.
Not sure that it adds a lot to the problem, but the diagnostics leading up to the exception being thrown look like the following:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 POST https://localhost:5001/callback application/x-www-form-urlencoded 396
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
AuthenticationScheme: Cookies signed in.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 634.9692ms 302
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 POST https://localhost:5001/callback application/x-www-form-urlencoded 396
fail: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[52]
Message contains error: 'invalid_grant', error_description: 'Invalid authorization code', error_uri: 'error_uri is null', status code '403'.
fail: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[17]
Exception occurred while processing message.
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_grant', error_description: 'Invalid authorization code', error_uri: 'error_uri is null'.
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest)
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()
info: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[4]
Error from RemoteAuthentication: Message contains error: 'invalid_grant', error_description: 'Invalid authorization code', error_uri: 'error_uri is null'..
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Exception: An error was encountered while handling the remote login.
---> Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_grant', error_description: 'Invalid authorization code', error_uri: 'error_uri
is null'.
回答1:
In case you want to add Auth0 in a Blazor WebAssembly project, you could just use the documentation from Microsoft.
However when using this for Auth0, there is one catch:
- It's not possible to provide the Audience, this means that you need to apply this work-around : Auth0-why-is-it-necessary-to-pass-the-audience-parameter-to-receive-a-jwt
Or you can use my NuGet package : WebAssembly.Authentication.Auth0 which does support the Audience parameter.
More details van be found here: https://github.com/StefH/Blazor.WebAssembly.Authentication.Auth0
来源:https://stackoverflow.com/questions/58983153/blazor-spa-authenticating-with-auth0-fails-on-callback