代码之家  ›  专栏  ›  技术社区  ›  kosnkov

Identity Server 4未删除cookie

  •  0
  • kosnkov  · 技术社区  · 6 年前

    我在Angular5上有前端应用程序,在C上有后端API,使用Identity Server。 问题是,当我单击注销按钮时,令牌被删除,我被重定向到注销页面。

    但是当我尝试刷新主页时,我被重定向到microsoftonline.com。 自动验证并重定向回主页面 我在这里缺少用户名和密码,这在chrome中出现。

    我注意到,如果我从microsoftonline.com手动删除cookie 然后重复这个过程,这一次我将被要求输入用户名和密码。

    所以首先我试着用这种方法清理所有的饼干,但没用

    foreach (var key in HttpContext.Request.Cookies.Keys)
    {
        HttpContext.Response.Cookies.Append(key, "", new CookieOptions() { Expires = DateTime.Now.AddDays(-1) });
    }
    

    以下是我的AccountController注销方法和cookie屏幕

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Logout(LogoutViewModel model)
    {
        var idp = User?.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
        var subjectId = HttpContext.User.Identity.GetSubjectId();
    
        if (idp != null && idp != IdentityServerConstants.LocalIdentityProvider)
        {
            if (model.LogoutId == null)
            {
                model.LogoutId = await interaction.CreateLogoutContextAsync();
            }
    
            try
            {
                await signInManager.SignOutAsync();
            }
            catch (NotSupportedException)
            {
            }
        }
    
        // set this so UI rendering sees an anonymous user
        HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
    
        // get context information (client name, post logout redirect URI and iframe for federated signout)
        var logout = await interaction.GetLogoutContextAsync(model.LogoutId);
    
        var vm = new LoggedOutViewModel
        {
            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,
            ClientName = logout?.ClientId,
            SignOutIframeUrl = logout?.SignOutIFrameUrl
        };
    
        await persistedGrantService.RemoveAllGrantsAsync(subjectId, "angular2client");
    
        return View("LoggedOut", vm);
    }
    

    enter image description here

    2 回复  |  直到 6 年前
        1
  •  1
  •   mackie    6 年前

    如果我理解正确,您是从IdentityServer4服务联合到Microsoft的吗?如果是这样,当您注销身份服务时,您还应该为用户提供注销外部提供者的选项(如果它支持相关功能-它需要定义一个 end_session_endpoint 在发现文档中)。

    标准OIDC中间件支持此功能,因此您应该能够通过调用signoutAsync()并传递MS联邦登录方案的名称来启动注销。

    另一种选择是始终发送 prompt=login 在外部登录请求中,然后检查 auth_time 声称你回来了。这样就可以强制交互式登录,并在发生时进行验证。

        2
  •  0
  •   m3n7alsnak3    6 年前

    尝试使用Identity Server提供的扩展方法从httpContext本身清除cookie,例如 here .

    或者试试这个:

    await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
    

    在注销控制器方法中。

    第三个选项(我在一个测试MVC客户机中拥有的是):

        public ActionResult Logout()
        {
            Request.GetOwinContext().Authentication.SignOut();
            return Redirect("/");
        }
    
        public void SignoutCleanup(string sid)
        {
            var cp = (ClaimsPrincipal)User;
            var sidClaim = cp.FindFirst("sid");
            if (sidClaim != null && sidClaim.Value == sid)
            {
                Request.GetOwinContext().Authentication.SignOut("Cookies");
            }
        }
    

    何处 Logout 方法是通过单击按钮调用的,并且 SignoutCleanup 是在将客户端注册为 Client.BackChannelLogoutUri (或) Client.FrontChannelLogoutUri 或者两者都有,取决于您的场景)。

    聚苯乙烯 :现在,总的来说,我认为你的做法是不对的,但我不知道你的全部情况,所以我不是在评判你——只是给予和建议。

    对于前端客户(Angular、Vue、Vanilla JS等),建议使用客户端 oidc-client-js 图书馆。和 here 是使用示例。如我所说,这只是一个建议,但是如果您正处于身份验证设置的最开始,我建议您看看。