应用在添加 Oauth 时重定向到 Account/AccessDenied
App redirects to Account/AccessDenied on adding Oauth
我偶然发现了一个问题,即在向当前登录用户添加社交媒体身份验证后,应用程序不一致地将用户重定向到 Account/AccessDenied/
。它似乎在用户第一次登录时工作,然后通过尝试添加另一种身份验证方法 returns 用户 Account/AccessDenied?ReturnUrl=%2Fmanage%2Flinklogincallback
.
我的猜测是 [Authorize] 属性出了问题,但这只是我第二次尝试添加外部身份验证方法。
管理控制器
[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<ActionResult> 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的排列顺序?
这是request/response
我已经得到从事安全存储库工作的 aspnet 团队的确认,这是一个错误(请参阅此 issue)并在下一个版本之前解决。
一个临时的解决方法是设置一个名为
的 cookie
Identity.External
为 null,这是在向您的帐户添加外部登录时创建的。
if (Request.Cookies["Identity.External"] != null)
{
Response.Cookies.Delete("Identity.External");
}
@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”
我也遇到了同样的问题。我使用的是来自 here
的 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<IOptions<IdentityOptions>>().Value.Cookies.ExternalCookieAuthenticationScheme;
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
DisplayName = "Google",
SignInScheme = CookieScheme,
ClientId = "xxx.apps.googleusercontent.com",
ClientSecret = "xxxx-Xxxxxxx"
});
我不得不从应用程序使用的当前身份系统的 cookie 选项中获取用于识别外部身份验证 cookie 的方案,而不是仅使用 IdentityServerConstants.ExternalAUthenticationScheme
中的常量 '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
并且 EmailConfirmed
字段是 false
对于外部身份验证的用户(例如 Facebook 登录),在后续登录时,您将被引导至 Account/AccessDenied/
操作方法。
我偶然发现了一个问题,即在向当前登录用户添加社交媒体身份验证后,应用程序不一致地将用户重定向到 Account/AccessDenied/
。它似乎在用户第一次登录时工作,然后通过尝试添加另一种身份验证方法 returns 用户 Account/AccessDenied?ReturnUrl=%2Fmanage%2Flinklogincallback
.
我的猜测是 [Authorize] 属性出了问题,但这只是我第二次尝试添加外部身份验证方法。
管理控制器
[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<ActionResult> 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的排列顺序?
这是request/response
我已经得到从事安全存储库工作的 aspnet 团队的确认,这是一个错误(请参阅此 issue)并在下一个版本之前解决。 一个临时的解决方法是设置一个名为
的 cookieIdentity.External
为 null,这是在向您的帐户添加外部登录时创建的。
if (Request.Cookies["Identity.External"] != null)
{
Response.Cookies.Delete("Identity.External");
}
@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”
我也遇到了同样的问题。我使用的是来自 here
的 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<IOptions<IdentityOptions>>().Value.Cookies.ExternalCookieAuthenticationScheme;
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
DisplayName = "Google",
SignInScheme = CookieScheme,
ClientId = "xxx.apps.googleusercontent.com",
ClientSecret = "xxxx-Xxxxxxx"
});
我不得不从应用程序使用的当前身份系统的 cookie 选项中获取用于识别外部身份验证 cookie 的方案,而不是仅使用 IdentityServerConstants.ExternalAUthenticationScheme
中的常量 '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
并且 EmailConfirmed
字段是 false
对于外部身份验证的用户(例如 Facebook 登录),在后续登录时,您将被引导至 Account/AccessDenied/
操作方法。