我有一个与Auth0集成的ASP.NET Core应用程序。身份验证之后,我想重定向到页面以收集信息以创建本地帐户,就像默认的Facebook和Google扩展程序一样。
我设置了一个主cookie,一个外部cookie和我的Auth0点。然后,它会回调到页面(/ Account / ExternalLogin),在我做完他们需要做的一切后,我在其中登录主cookie,然后重定向到需要授权的页面(/ Profile。这一切正常。>
但是,如果我只是尝试转到该页面而不是通过登录路径,则会陷入循环。
我很确定我只是想念一件愚蠢的事情,但似乎无法做到。
我已经尽力将所有我能弄清楚并碰壁的东西组合在一起。我敢肯定这很愚蠢。
这是我与startup.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");
});
}
这是AccountController
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")
});
}
}
因此,我们重定向到ExternalLogin回调。当前,只有一个提交按钮转到确认回调,以完成登录。最终将用一张支票取代该支票,以查看我是否拥有他们的帐户,并强迫他们注册。
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");
}
}
因此,当我转到/ Account / Login时,它将正确地将我发送到Auth0,然后将其发送到ExternalLogin,然后单击按钮并设置主Cookie。然后,这可以让我访问/ Profile。
但是,如果我没有被授权,如果我执行/ Profile,那么我将跳到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
答案 0 :(得分:1)
只需更改选项。将DefaultChallengeScheme =“ Auth0”更改为选项。DefaultChallengeScheme=“ MainCookie”。