Blazor SPA的Auth0身份验证在回调时失败 [英] Blazor SPA authenticating with Auth0 fails on callback

查看:98
本文介绍了Blazor SPA的Auth0身份验证在回调时失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在按照

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:消息包含错误:'invalid_grant',error_description:'无效的授权码',error_uri:'error_uri为空'

OpenIdConnectProtocolException: Message contains error: 'invalid_grant', error_description: 'Invalid authorization code', error_uri: 'error_uri is null'

/callback URL.

at the /callback URL.

如果我查看日志,可以看到Auth0端发生了三个事件:

If I check the logs, I can see there are three events happening at the Auth0 end:

  • 成功登录
  • 访问令牌的授权代码
  • 无效的授权码

一个接一个.我可以看到那些授权代码在成功交换"和失败交换"条目之间确实匹配.

Each straight after the other. I can see those authorization codes do match between the "Success Exchange" and the "Failed Exchange" entries.

我可以看到实际上已经进行了Auth0身份验证,并且如果浏览到应用程序中的其他页面,我可以看到我已成功登录,但是对/callback URL的初始回调阻止了他们的前进.中间件/Startup.cs代码中是否缺少某些内容,或者还有其他内容需要检查Auth0应用程序设置吗?

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?

为避免疑问,我已精确复制了博客文章代码,并可以确认应用程序确实进行身份验证并登录我.这是Startup.cs中的代码:

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'.

推荐答案

如果要在Blazor WebAssembly项目中添加Auth0,则可以使用

In case you want to add Auth0 in a Blazor WebAssembly project, you could just use the documentation from Microsoft.

但是,将其用于Auth0时,有一个陷阱:

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

或者您可以使用我的NuGet包: WebAssembly.Authentication.Auth0 它确实支持 Audience 参数.

Or you can use my NuGet package : WebAssembly.Authentication.Auth0 which does support the Audience parameter.

更多详细信息可以在这里找到: https://github.com/StefH/Blazor.WebAssembly.Authentication.Auth0

More details van be found here: https://github.com/StefH/Blazor.WebAssembly.Authentication.Auth0

这篇关于Blazor SPA的Auth0身份验证在回调时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆