无法让 IdentityServer4 注销用于外部 (Google) 身份验证
Can't get IdentityServer4 logout to work for external (Google) authentication
我正在通过 IdentityServer4 快速启动并尝试使外部 (Google) 身份验证工作。我可以通过 Google 登录,但是在登录之后,即使我点击注销,我总是会在以下时间自动进入。
这是来自 AccountController.cs
的注销逻辑
/// <summary>
/// Handle logout page postback
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout(LogoutInputModel model)
{
// build a model so the logged out page knows what to display
var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);
if (User?.Identity.IsAuthenticated == true)
{
// delete local authentication cookie
await _signInManager.SignOutAsync();
// raise the logout event
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
}
// check if we need to trigger sign-out at an upstream identity provider
if (vm.TriggerExternalSignout)
{
// build a return URL so the upstream provider will redirect back
// to us after the user has logged out. this allows us to then
// complete our single sign-out processing.
string url = Url.Action("Logout", new { logoutId = vm.LogoutId });
// this triggers a redirect to the external provider for sign-out
return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
}
return View("LoggedOut", vm);
}
顺便说一句,我的内部身份验证登录和注销工作正常。有人能告诉我这里可能遗漏了什么吗?
Update-1
进一步调试发现注销时Logout函数中vm.TriggerExternalSignout的值始终为false。变量TriggerExternalSignout在整个解决方案的源代码中只出现了两次。第一个在上面的 Logout 中,另一个在 LoggedOutViewModel.cs 中,如下所示:
TriggerExternalSignout 为假的直接原因是 属性 ExternalAuthenticationScheme 的值始终为空。唯一设置 ExternalAuthenticationScheme 的地方是在 AccountController 的 BuildLoggedOutViewModelAsync 函数中(见下面的屏幕截图),在登录和注销期间似乎从未调用过(断点永远不会被击中)。
那是因为 providerSupportsSignout 的值为 false。这是有道理的,因为 Google 不支持注销,但我应该怎么做才能让我的注销正常工作?
Update-2
我在 BuildLoggedOutViewModelAsync 函数中添加了注销逻辑,正如 nahidf 在他的回答中所建议的那样:
不幸的是,注销似乎仍然不起作用 - 我在从 Google 登录中单击注销后进入了显示我已注销的页面,但我仍然可以通过单击 Google 尝试开始新会话时的登录按钮。
我做错了什么?
- 检查你的情况下
TriggerExternalSignout
是否为 true
,如果不是,应调查原因
- 如果
TriggerExternalSignout
已经为真,尝试
// delete local authentication cookie
await HttpContext.SignOutAsync();
// Clear the existing external cookie to ensure a clean login process
wait HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
当我们从 IdentityServer4 注销时,它只是将用户从我们的应用程序中注销。它将 NOT 将用户注销其 Google 帐户。 Google不支持第三方登出。
编辑:对于 google 案例 TriggerExternalSignout
是 false
因为 google 不支持外部注销。 Ref in code
我正在通过 IdentityServer4 快速启动并尝试使外部 (Google) 身份验证工作。我可以通过 Google 登录,但是在登录之后,即使我点击注销,我总是会在以下时间自动进入。
这是来自 AccountController.cs
的注销逻辑/// <summary>
/// Handle logout page postback
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout(LogoutInputModel model)
{
// build a model so the logged out page knows what to display
var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);
if (User?.Identity.IsAuthenticated == true)
{
// delete local authentication cookie
await _signInManager.SignOutAsync();
// raise the logout event
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
}
// check if we need to trigger sign-out at an upstream identity provider
if (vm.TriggerExternalSignout)
{
// build a return URL so the upstream provider will redirect back
// to us after the user has logged out. this allows us to then
// complete our single sign-out processing.
string url = Url.Action("Logout", new { logoutId = vm.LogoutId });
// this triggers a redirect to the external provider for sign-out
return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
}
return View("LoggedOut", vm);
}
顺便说一句,我的内部身份验证登录和注销工作正常。有人能告诉我这里可能遗漏了什么吗?
Update-1
进一步调试发现注销时Logout函数中vm.TriggerExternalSignout的值始终为false。变量TriggerExternalSignout在整个解决方案的源代码中只出现了两次。第一个在上面的 Logout 中,另一个在 LoggedOutViewModel.cs 中,如下所示:
TriggerExternalSignout 为假的直接原因是 属性 ExternalAuthenticationScheme 的值始终为空。唯一设置 ExternalAuthenticationScheme 的地方是在 AccountController 的 BuildLoggedOutViewModelAsync 函数中(见下面的屏幕截图),在登录和注销期间似乎从未调用过(断点永远不会被击中)。
那是因为 providerSupportsSignout 的值为 false。这是有道理的,因为 Google 不支持注销,但我应该怎么做才能让我的注销正常工作?
Update-2
我在 BuildLoggedOutViewModelAsync 函数中添加了注销逻辑,正如 nahidf 在他的回答中所建议的那样:
不幸的是,注销似乎仍然不起作用 - 我在从 Google 登录中单击注销后进入了显示我已注销的页面,但我仍然可以通过单击 Google 尝试开始新会话时的登录按钮。
我做错了什么?
- 检查你的情况下
TriggerExternalSignout
是否为true
,如果不是,应调查原因 - 如果
TriggerExternalSignout
已经为真,尝试
// delete local authentication cookie
await HttpContext.SignOutAsync();
// Clear the existing external cookie to ensure a clean login process
wait HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
当我们从 IdentityServer4 注销时,它只是将用户从我们的应用程序中注销。它将 NOT 将用户注销其 Google 帐户。 Google不支持第三方登出。
编辑:对于 google 案例 TriggerExternalSignout
是 false
因为 google 不支持外部注销。 Ref in code