应用程序在添加Oauth时重定向到Account / AccessDenied

我偶然发现了一个问题,即在向当前登录用户添加社交媒体身份validation时,应用程序将用户重定向到Account/AccessDenied/不一致。 它似乎在用户第一次登录时工作,然后通过尝试添加另一个身份validation方法,它将用户返回到Account/AccessDenied?ReturnUrl=%2Fmanage%2Flinklogincallback

我的猜测是[Authorize]属性出了问题,但只是第二次尝试添加外部身份validation方法。

ManageController

 [Authorize] public class ManageController : Controller { // // POST: /Manage/LinkLogin [HttpPost] [ValidateAntiForgeryToken] public IActionResult LinkLogin(string provider) { // Request a redirect to the external login provider to link a login for the current user var redirectUrl = Url.Action("LinkLoginCallback", "Manage"); var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User)); return Challenge(properties, provider); } // // GET: /Manage/LinkLoginCallback [HttpGet] public async Task LinkLoginCallback() { var user = await GetCurrentUserAsync(); if (user == null) { return View("Error"); } var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user)); if (info == null) { return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error }); } var result = await _userManager.AddLoginAsync(user, info); var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error; return RedirectToAction(nameof(ManageLogins), new { Message = message }); } } 

这可能是startup.cs如何安排的顺序?

这是请求/响应

在此处输入图像描述

@Rovdjuret的解决方法帮助了我,直到asp.net团队解决了它。 这是我的控制器登录操作:

 public IActionResult Login(string returnUrl = null) { if (_signInManager.IsSignedIn(User)) { // redirect to user profile page return RedirectToAction(nameof(HomeFileController.Index), "HomeFile"); } else { // clear Identity.External cookie if (Request.Cookies["Identity.External"] != null) { Response.Cookies.Delete("Identity.External"); } return View(new LoginViewModel{ ReturnUrl = returnUrl, RememberMe = true }); } } 

更新:在最新版本(截至2017年5月),cookie的前缀为“.AspNetCore。”。 因此cookie名称应为“ .AspNetCore.Identity.External

我也遇到了同样的问题。 我从这里使用IdentityServer4 QuickStart示例中的代码

  app.UseGoogleAuthentication(new GoogleOptions { AuthenticationScheme = "Google", DisplayName = "Google", SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme, ClientId = "xxx.apps.googleusercontent.com", ClientSecret = "xxxx-Xxxxxxx" }); 

我不得不将代码更改为以下内容以解决问题。

  var CookieScheme= app.ApplicationServices.GetRequiredService>().Value.Cookies.ExternalCookieAuthenticationScheme; app.UseGoogleAuthentication(new GoogleOptions { AuthenticationScheme = "Google", DisplayName = "Google", SignInScheme = CookieScheme, ClientId = "xxx.apps.googleusercontent.com", ClientSecret = "xxxx-Xxxxxxx" }); 

我不得不使用IdentityServerConstants.ExternalAUthenticationScheme的常量“外部”,而是必须获取用于从应用程序使用的当前身份系统的cookie选项中识别外部身份validationcookie的方案。 这就是为我解决问题的原因。

我已经得到了安全回购的aspnet团队的证实,这是一个错误(请参阅此问题 )并解决到下一个版本。 临时解决方法是设置名为的cookie

Identity.External

为null,这是在向您的帐户添加外部登录时创建的。

 if (Request.Cookies["Identity.External"] != null) { Response.Cookies.Delete("Identity.External"); } 

解决方法帮助了我,直到它被asp.net团队解决

  // GET: /Account/AccessDenied [HttpGet] [AllowAnonymous] public IActionResult AccessDenied(string returnUrl = null) { // workaround if (Request.Cookies["Identity.External"] != null) { return RedirectToAction(nameof(ExternalLoginCallback), returnUrl); } return RedirectToAction(nameof(Login)); } 

如果您在Startup.cs设置了config.SignIn.RequireConfirmedEmail = true ,并且对于外部认证的用户(例如Facebook登录), EmailConfirmed字段为false ,则在后续登录时,您将被定向到Account/AccessDenied/ action方法。