我们一直在利用.NET Core 2.2应用程序中的Cookie身份验证,并在通过Microsoft外部第三方提供商验证其身份之后登录用户。就在最近,我们在此工作流程中发现了一个错误,指出:
Microsoft.AspNetCore.Authentication.MicrosoftAccount.MicrosoftAccountHandler:信息:RemoteAuthentication中的错误:关联失败。”
我们将其范围缩小到以下情况:如果用户已经登录到其Microsoft帐户(仅一个帐户已登录/处于活动状态)...,然后他们登录到我们的网站,则会自动登录无需选择他们的帐户名称或任何其他互动。此外,如果用户确实单击其帐户名,则会触发另一个登录请求,并且我认为由于请求/响应cookie冲突而导致“关联失败。”错误。
尽管我们真正的托管服务提供商位于Azure(App Services)中,但我仍可以从本地主机重现该问题。
我已经探索了以下Microsoft文档中提到的一些解决方案/方法,这些文档提到了负载平衡器和代理服务器(转发标头)的配置...以及在ASP.NET Core中实施HTTPS:
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1
这些似乎没有解决问题的根源,据我了解,这是对Microsoft提供商进行安全挑战时自动登录/选择用户帐户的问题。
这是我们的Startup.cs服务配置中的第三方身份验证配置的摘录。
// Authentication is added via Cookie
services.ConfigureApplicationCookie(options => options.LoginPath = "/Login");
services.AddAuthentication(opts =>
{
opts.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
opts.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(opts =>
{
opts.Cookie.SecurePolicy = CookieSecurePolicy.Always;
opts.LoginPath = "/auth/login";
opts.LogoutPath = "/auth/logout";
opts.ClaimsIssuer = "<ISSUER_HERE>"; // *** redacted for privacy
})
.AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["Authentication:ApplicationId"];
options.ClientSecret = Configuration["Authentication:Password"];
options.Events.OnRemoteFailure = ctx =>
{
// React to the error here. See the notes below.
ctx.Response.Redirect("/error?FailureMessage=" + UrlEncoder.Default.Encode(ctx.Failure.Message));
ctx.HandleResponse();
return Task.FromResult(0);
};
});
理想情况下,阻止了“自动登录”行为,因此用户必须从Microsoft帐户选择提示中选择他们的帐户(即使他们以前已经登录)。
现在,我们将用户重定向到错误页面,在这里我们可以清除所有cookie,并让用户重新尝试登录。如果他们在登录过程中不断选择他们的用户帐户,并且两个请求都冲突,则会造成问题。
任何见识将不胜感激!
答案 0 :(得分:2)
那好吧,我明白了。
似乎有点hacky,但是,它可以工作。
.AddMicrosoftAccount(options =>
{
// Your configuration here
options.Events.OnRedirectToAuthorizationEndpoint = context =>
{
context.HttpContext.Response.Redirect(context.RedirectUri + "&prompt=select_account");
return Task.FromResult(0);
};
})