【问题标题】:IdentityServer4 logoutIdentityServer4 注销
【发布时间】:2018-08-13 07:19:07
【问题描述】:

我遇到了一个问题,我似乎无法让我的 Identity Server 注销以首先显示确认信息。我从github下载了IdentityServer4的源代码,在Models文件夹中找到了参数:LogoutRequest.cs, ShowSignOutPrompt。 IdentityServer 中没有对它的引用,除了在注销期间检查它。

在调试中,我看到它是错误的。我不知道应该在哪里设置,我已经检查了服务器和客户端的客户端配置选项,以及服务器启动的选项。

我在客户端代码中找不到“ShowSignoutPrompt”的实例(我目前使用的是 IdentityServer3 Owin Hybrid 客户端示例)。

代码流程如下: 我们的默认布局中有一个按钮触发客户端的 AccountController.Signout():

public void Signout()
{
    Request.GetOwinContext().Authentication.SignOut();
}

从那里开始,我不完全确定如何,但它命中的下一点是 IdentityServer 的 AccountController.Logout(string logoutId)。该方法构建注销提示视图(使用 AccountServices.BuildLogoutViewModelAsync 中的检查)并将其返回到用户的浏览器。不将 ShowSignoutPrompt 设置为 false 的唯一方法是将 PostLogoutRedirectUri 设置为“/signout-callback-oidc”。我不知道为什么。

当用户在上面生成的视图上单击“是”时,它会转到 IdSrvr 的 AccountController.Logout(LogoutInputModel 模型)。我正在尝试更改该方法的最后一行:

return View("LoggedOut", vm);

到:

return Redirect(vm.PostLogoutRedirectUri);

这里的另一个问题是 PostRedirectUri 在这里为空,即使我在客户端配置中设置了它(好吧,就此而言,Identity Server 的客户端配置也有它)。

【问题讨论】:

  • 如果我将 PostLogoutRedirectUri 设置为“/signout-callback-oidc”,则它会成功显示注销提示,但随后会在 IdentityServer AccountController 中引发错误,因为 AccountService.BuildLoggedOutViewModelAsync 正在返回空视图模型。
  • 我还在 IdentityServer 主机控制器文件夹中看到了 AccountOptions.cs。我目前的价值观是: ShowLogoutPrompt = true; AutomaticRedirectAfterSignOut = false;我很快就会尝试自动重定向,我想我太早了。
  • 如果您使用外部身份提供者,其他人应该注意的是,AccountController 的 Logout(string logoutId) 方法实际上被调用了很多次 (3):1.第一次从客户端的 Signout() 方法触发。 2. 用户在确认注销视图上单击“是”后。 3. 在外部身份提供者在那端注销用户后返回控制权(由 Logout(LoggedOutViewModel) 方法触发。这可能会导致很多混乱。我还没有。
  • 我在尝试注销以提示并返回客户端的注销页面时问了两个单独的问题,这个和这个:stackoverflow.com/questions/49117283/… 我已将以下标记为答案,因为它澄清了很多有点,如果这还不够信息,我也回答了另一个问题。

标签: .net identityserver4 asp.net-authentication


【解决方案1】:

没有客户端属性可以控制这一点。

当注销客户端应用程序调用 IdentityServer4 End Session Endpoint

当客户端发送原始 id_token 时,可以绕过注销提示。 这是作为 id_token_hint 参数传入的。

此外,它指示注销请求是否已通过身份验证,因此不提示用户注销是安全的。 per ref

ShowSignoutPrompt 指示是否应根据传递给结束会话端点的参数提示用户退出。 来源PDF

注意: 如果您使用 JavaScript OIDC-Client-JS 库,“signoutRedirect”方法将在内部检查,请参阅 _signoutStart method 第 354 行,了解 id_token_hint 参数或用户 id_token。因此,如果您使用此库注销用户并想要强制退出屏幕,则必须清除 user.id_token。

来自 _signoutStart() 的示例部分

_signoutStart(args = {}, navigator, navigatorParams = {}) {
    ...
    var id_token = args.id_token_hint || user && user.id_token;
    if (id_token) {
        Log.debug("Setting id_token into signout request");
        args.id_token_hint = id_token;
    }
    ...
}

更新:

如果您使用 IdentityServer4 版本 2.x,您可以使用新类 ClientProperty 来存储键值对。在这里,您可以创建一个键“LogoffPromptRequired”和一个值“true”,用于客户端或 IdentityServer 实现,以确定是否需要注销屏幕。

【讨论】:

  • 所以如果我想强制注销提示,我应该修改客户端不发送我猜的id_token。
  • 您有什么类型的客户? C# API,具有 JavaScript 的 Web 客户端?
  • 客户端的原始来源来自 IdentityServer 示例,MVC Owin Hybrid。必须使用它才能使 .NET 标准项目与 .NET Core IdentityServer4 一起使用。客户端来自 IdentityServer3,但仍与 IdentityServer4 一起使用。
  • 您能否在问题详细信息中分享该客户的注销代码?
  • @aaronR 在使用 oidc-client-js 库时,是否还有一个选项可以绕过身份服务器的注销屏幕?我正在编写一个注销功能来踢出空闲的用户。我使用了 createSignoutRequest(id_token_hint: user.id_token) 并对这个端点执行了 GET 请求,但它不起作用。
【解决方案2】:

我建议在客户端应用程序中实现提示,然后在完成后重定向到 endsession。

【讨论】:

  • 你是说让用户决定是否应该显示注销提示?
  • 我想出了如何让 IdentityServer 获取 PostLogoutRedirectUri,将提供相关详细信息以及导致服务器端为空的陷阱/兔子洞的答案。感谢大家的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-01-17
  • 1970-01-01
  • 2018-07-17
  • 2021-07-05
  • 2019-02-08
  • 2019-11-18
  • 2020-09-11
  • 1970-01-01
相关资源
最近更新 更多