【问题标题】:Logging out from Identity Server 4 won't log out from Client从 Identity Server 4 注销不会从客户端注销
【发布时间】:2020-04-10 08:44:48
【问题描述】:

我和https://github.com/IdentityServer/IdentityServer4/issues/3153有类似的问题

我正在使用 Asp Net Identity 和 EF Core 组合示例,除了我尝试从 IS 页面注销时,一切正常,数据库、种子、api 调用。它不会删除.AspNetCore.Cookies,它是保持用户在客户端登录的那个。

    [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)
        {
            _log.LogCustomInfo(LoggingType.Information, "<AUDIT>" + "Logout: User Is Authenticated" + "</AUDIT>");

            try
            {
                await _signInManager.SignOutAsync();
                await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
                await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
                // raise the logout event
                await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
            }
            catch (NotSupportedException)
            {
                _log.LogCustomInfo(LoggingType.Information, "<AUDIT>" + "Logout: SignOutAsync Not Supported" + "</AUDIT>");
            }

        }

        /* https://github.com/IdentityServer/IdentityServer4/issues/855 */
        // check if we need to trigger sign-out at an upstream identity provider

        // delete local authentication cookie
        Response.Cookies.Delete(".AspNetCore.Identity.Application");
        Response.Cookies.Delete("idserv.external");
        Response.Cookies.Delete("idserv.session");


        _log.LogCustomInfo(LoggingType.Information, "<AUDIT>" + "Logout: Trigger external signout " + vm.TriggerExternalSignout +  "</AUDIT>");

        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 });
            //url = _configuration["AppSettings:PostLogoutRedirectUri"]; 
            url = vm.PostLogoutRedirectUri;
            //url = "redirect.html";
                                            // this triggers a redirect to the external provider for sign-out
            _log.LogCustomInfo(LoggingType.Information, "<AUDIT>" + "Logout: Redirect to " + url +  "</AUDIT>");

            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
        }

        return View("LoggedOut", vm);
    }

我在 Angular 客户端和 MVC 应用程序中遇到了同样的问题。

如果我手动删除.AspNetCore.Identity.Application,客户端将被注销。我正在使用keycloak 进行身份验证并使用

    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    options.SignOutScheme = IdentityServerConstants.SignoutScheme;

在启动IS配置选项中。

【问题讨论】:

    标签: angular security .net-core identityserver4


    【解决方案1】:

    我知道这是一个老问题,但我也遇到了同样的问题。

    事实证明,我从回购中获得的代码没有删除问题所做的 cookie 的行。添加后,注销实际上已注销。

    Response.Cookies.Delete(".AspNetCore.Identity.Application");
    Response.Cookies.Delete("idserv.external");
    Response.Cookies.Delete("idserv.session");
    

    该 repo 适用于当前最新的 IdentityServer4 4.1.1,并且应该可以正常工作,因为它是演练的结果。

    【讨论】:

    • 我正在运行这些确切的行,但愚蠢的 cookie 仍然存在。就是拒绝迷路!您能否发布一个指向您的解决方法来源的链接,好吗?并随时建议还需要做什么才能使这些行真正从浏览器中删除内容。
    • @KonradViltersten,我无法再访问该代码库了,因为我换了工作。我希望我能提供更多帮助,但如果没有该代码,我只是在猜测。我也不知道我使用了哪个公共回购或演练,因为在我开始工作之前我至少经历了 5 次,那也是 10 个月前的事。对不起。
    【解决方案2】:

    应用程序 Cookie 应由客户端应用程序删除。

    如果您在应用程序中启动注销,您必须从两种方案、Cookie 和 oidc 中注销。例如:

    public IActionResult Logout()
    {
        return SignOut(new[] { "Cookies", "oidc" });
    }
    

    这样你已经删除了客户端的cookie。

    如果您在 Idp 中启动注销,则可以使用以下规范之一使用全局注销机制:

    这样您就可以从您在同一会话中登录的所有应用程序客户端注销。

    所有这些都被身份服务器 4 支持。

    【讨论】:

    • 这对我不起作用。我需要注销才能使用重定向 url。如果我对我的 SignOut 调用进行以下更改,.AspNetCore.Identity.Application cookie 仍然没有被删除。 return SignOut(new AuthenticationProperties { RedirectUri = url }, "Cookies", "oidc", IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme, vm.ExternalAuthenticationScheme);
    • 我所指的注销是针对应用程序的,而不是针对身份提供者的。仅当从应用程序启动注销时才可能。否则,您无法直接从身份提供者中删除应用程序会话 cookie。使用三种全局注销方法之一来获取它。
    【解决方案3】:

    我可以通过手动删除应用程序 cookie 来注销。起初我在删除它时遇到了问题,因为我没有指定应用程序路径。指定cookie路径后,就可以删除cookie了。

      Response.Cookies.Delete(".AspNetCore.Identity.Application", new CookieOptions()
        {
            Path = "/eds-daas"
        });
    

    【讨论】:

      【解决方案4】:

      我使用单独的 API 构建了一个 MVC 应用程序。我使用 IdentityServer4 进行身份验证,并按照上述步骤将 Response.Cookies.Delete 添加到 IdentityServer4 的 AccountController 中,效果很好。无论如何,我的客户保留了它的 cookie。

      为了将它们从客户端中删除,我在 Logout 方法中添加了相同的行,然后再返回 SignOut。

          /// <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)
              {
                  Response.Cookies.Delete(".AspNetCore.Identity.Application");
                  Response.Cookies.Delete("idserv.external");
                  Response.Cookies.Delete("idserv.session");
      
                  // delete local authentication cookie
                  await HttpContext.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 { IsPersistent = true, RedirectUri = url }, vm.ExternalAuthenticationScheme);
              }
      
              return View("LoggedOut", vm);
          }
      

      【讨论】:

        猜你喜欢
        • 2019-06-06
        • 2020-04-27
        • 2020-10-06
        • 1970-01-01
        • 1970-01-01
        • 2021-03-14
        • 2019-07-02
        • 2020-11-16
        • 2021-07-30
        相关资源
        最近更新 更多