从Identity Server 4注销将不会从客户端注销

时间:2019-12-17 19:49:28

标签: angular security .net-core identityserver4

我有一个与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);
    }

我从角度客户端和MVC应用程序遇到了同样的问题。

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

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

在启动IS配置选项中。

4 个答案:

答案 0 :(得分:1)

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

事实证明,我从 repo 获得的代码没有删除问题所做的 cookie 的行。一旦我添加它,注销实际上已注销。

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

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

答案 1 :(得分:0)

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

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

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

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

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

这样,您可以从同一时间通过同一会话登录的所有应用程序客户端中退出。

身份服务器4支持所有这些功能。

答案 2 :(得分:0)

我能够通过手动删除应用程序cookie登出。一开始我在删除它时遇到问题,因为我没有指定应用程序路径。指定cookie路径后,可以删除cookie。

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

答案 3 :(得分:0)

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

为了从客户端中删除它们,我在返回 SignOut 之前向 Logout Method 添加了相同的行。

    /// <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);
    }