问题描述
这里我想实现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);
}
}