剃须刀页面授权与外部cookie陷入循环



我有一个与auth0集成的ASP.NET核心应用程序。身份验证后,我想重定向到页面以收集信息以创建本地帐户,就像默认的Facebook和Google Extensions一样。

我设置了一个主曲奇,外部cookie和我的auth0点。然后,它将回调到页面(/account/externallogin(,在执行他们需要做的任何事情之后,我登录主cookie,然后重定向到需要授权的页面(/profile。这一切都很好。p>但是,如果我只是尝试转到该页面而不是通过登录路线,我就会陷入循环。

我很确定我只错过了一件愚蠢的事情,但似乎无法得到。

我尝试将几乎所有可以找到并撞到墙的东西组合。我确定这是愚蠢的。

这是我的相关部分。cs

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    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 = "MainCookie";
        options.DefaultChallengeScheme = "Auth0";
    })
    .AddCookie("MainCookie", options =>
    {
        options.ForwardChallenge = "Auth0";
    })
    .AddCookie("External", options =>
    {
    })
    .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");
        options.Scope.Add("profile");
        options.Scope.Add("email");
        options.SignInScheme = "External";
        // 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;
                    }
        };
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddRazorPagesOptions(options =>
            {
                options.Conventions.AuthorizePage("/Profile");
            });
}

此处的帐户controller

public class AccountController : Controller
{
    public async Task Login(string returnUrl = "/")
    {
        var redirectUrl = Url.Page("/ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
        await HttpContext.ChallengeAsync("Auth0", new AuthenticationProperties() { RedirectUri = redirectUrl });
    }
    [Authorize]
    public async Task Logout()
    {
        await HttpContext.SignOutAsync("External");
        await HttpContext.SignOutAsync("MainCookie");
        await HttpContext.SignOutAsync("Auth0", new AuthenticationProperties
        {
            RedirectUri = Url.Action("Index", "Home")
        });
    }
}

因此,我们将其重定向到外login回调。当前,只有一个提交按钮可以使用确认回调,该回调完成了登录名。最终将用一张支票替换,以查看我是否有帐户,并迫使他们注册。

public class ExternalLoginModel : PageModel
{
    public IActionResult OnPost(string provider, string returnUrl = null)
    {
        var redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
        return new ChallengeResult(provider, null);
    }

    public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");
        if (remoteError != null)
        {
            ErrorMessage = $"Error from external provider: {remoteError}";
            return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
        }
        return Page();
    }
    public async Task<IActionResult> OnPostConfirmAsync()
    {
        var claimsPrincipal = await HttpContext.AuthenticateAsync("External");
        await HttpContext.SignInAsync("MainCookie", claimsPrincipal.Principal);
        await HttpContext.SignOutAsync("External");
        return RedirectToPage("/Profile");
    }
}

因此,当我去/帐户/登录时,它会正确地将我发送到Auth0,然后将其发送到外蓝蛋白,然后单击按钮并设置主cookie。然后让我访问/个人资料。

但是,如果我尚未授权,如果我执行/配置文件,则踢到Auth0,但是在认证后,我只是陷入了这样的循环。

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/2.0 GET https://localhost:44375/profile  
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executing endpoint 'Page: /Profile'
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker:Information: Route matched with {page = "/Profile", action = "", controller = ""}. Executing page /Profile
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler:Information: AuthenticationScheme: Auth0 was challenged.
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker:Information: Executed page /Profile in 11.2594ms
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executed endpoint 'Page: /Profile'
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 28.548ms 302 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/2.0 POST https://localhost:44375/callback application/x-www-form-urlencoded 375
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: External signed in.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 113.1223ms 302 

更改options.defaultchallengescheme =" auth0" to options.defaultchallengescheme =" maincookie"就是所需的一切。

最新更新