微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

身份服务器 4 使用 FrontChannelLogoutUri 从所有客户端注销不起作用

如何解决身份服务器 4 使用 FrontChannelLogoutUri 从所有客户端注销不起作用

这里我想实现SSO功能。如果我从身份服务器注销,所有与该用户 ID 连接的客户端都应该注销。但它对我有用。

我使用的是 Identity Server Version="4.0.0"

我已经设置了 IDS 客户端、用于注销的 UI 模板、MVC 客户端,如下所示。但并不是所有客户端都退出

new Client
    {
        ClientId = "testmvc",AllowedGrantTypes = GrantTypes.Code,// secret for authentication
        ClientSecrets =
        {
            new Secret("Secret".Sha256())
        },AllowOfflineAccess = true,// scopes that client has access to
        AllowedScopes = new List<string>
        {
            IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.Address,"roles"
        },// where to redirect to after login
        RedirectUris = { "https://localhost:5002/signin-oidc" },// where to redirect to after logout
        PostlogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },FrontChannellogoutUri  = "https://localhost:5002/home/frontchannellogout",}

在 MVC 客户端中,我创建了两次注销

//UI logout
public async Task<IActionResult> logout()
        {

            var client = _httpClientFactory.CreateClient("IDPClient");

            var discoveryDocumentResponse = await client.GetdiscoveryDocumentAsync();
            if (discoveryDocumentResponse.IsError)
            {
                throw new Exception(discoveryDocumentResponse.Error);
            }

            var accesstokenRevocationResponse = await client.RevoketokenAsync(
                new TokenRevocationRequest
                {
                    Address = discoveryDocumentResponse.RevocationEndpoint,ClientId = "testmvc",ClientSecret = "Secret",Token = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.Accesstoken)
                });

            if (accesstokenRevocationResponse.IsError)
            {
                throw new Exception(accesstokenRevocationResponse.Error);
            }
            
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
            
            return Redirect(discoveryDocumentResponse.EndSessionEndpoint);
        }

//Front channel logout
            public async Task<IActionResult> FrontChannellogout(string sid)
            {
                if (User.Identity.IsAuthenticated)
                {
                    var currentSid = User.FindFirst("sid")?.Value ?? "";
                    if (string.Equals(currentSid,sid,StringComparison.Ordinal))
                    {
                        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                    }
    
                }
    
                return NoContent();
            }

解决方法

Logout 方法中,您从两种身份验证方案(Cookie 和 OIDC)中注销,而在 FrontChannelLogout 中,您似乎只从 Cookie 方案中注销。这不是问题吗?

无论哪种方式,请尝试定义如下方法,并检查是否调用了相应的 OIDC 注销端点。

public async Task Logout()
{
    // ...
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}

public async Task FrontChannelLogout(string sid)
{
    if (User.Identity.IsAuthenticated)
    {
        //...
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。