从Identity Server 4注销不会导致客户端注销

6

我有一个类似于https://github.com/IdentityServer/IdentityServer4/issues/3153的问题。

我使用了Asp Net Identity和EF Core组合示例,一切都工作正常,包括数据库、种子数据和api调用,但当我尝试从IS页面注销时,它无法删除.AspNetCore.Cookies,这个cookie是保持用户在客户端登录的。

    [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 配置选项中。
4个回答

3

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

事实证明,我从存储库获取的代码没有删除Cookie的代码行。一旦我添加了它,注销实际上就成功注销了。

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

该存储库是针对当前最新的IdentityServer4 4.1.1版本的,并且应该可以工作,因为它是通过逐步操作得出的结果。

我正在运行确切的代码,但是这些可恶的cookie仍然存在。他们就是不肯消失!你能否发一下你解决问题的源链接?并且请随意建议还需要做什么来让这些代码真正从浏览器中删除这些东西。 - Konrad Viltersten
@KonradViltersten,我无法再访问代码库了,因为我换了工作。我希望我能提供更多帮助,但没有那些代码,我只会瞎猜。而且我也不知道我使用了哪个公共存储库或步骤说明,因为在我使事情正常化之前,我至少尝试过5种不同的。那还是10个月以前的事了。抱歉。 - computercarguy

2

我能够通过手动删除应用程序cookie来注销。一开始我无法删除它,因为我没有指定应用程序路径。在我指定了cookie路径后,我就能够删除cookie了。

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

1
我使用了分离的API构建了一个MVC应用程序。我使用IdentityServer4进行身份验证,并按照上述步骤在IdentityServer4的AccountController中添加了Response.Cookies.Delete,效果很好。但是,我的客户端仍然保留了它的Cookies。
为了从客户端中删除它们,在返回SignOut之前,我在Logout方法中添加了相同的行。
    /// <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);
    }

1
应用程序Cookie应该由客户端应用程序删除。
如果您在应用程序中启动注销,则必须从Cookies和oidc两个方案中注销。例如:
public IActionResult Logout()
{
    return SignOut(new[] { "Cookies", "oidc" });
}

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

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

这样,您就可以从所有应用程序客户端中注销,在此同时使用相同的会话。

它们都受Identity Server 4的支持。


这对我不起作用。我需要注销功能与重定向URL一起工作。 如果我对我的SignOut调用进行以下更改,则仍未删除.AspNetCore.Identity.Application cookie。return SignOut(new AuthenticationProperties { RedirectUri = url }, "Cookies", "oidc", IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme, vm.ExternalAuthenticationScheme); - John Bowyer
我所提到的注销是针对应用程序而不是身份提供者的。只有在从应用程序发起注销时才可能实现。否则,您无法直接从身份提供者中删除应用程序会话cookie。请使用三种全局注销方法之一来获取它。 - Alpha75

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接