Duende Identity Server:ASP.NET4.6.2客户端登出后LogoutContext参数为空
核心原因
ASP.NET 4.6.2使用的Microsoft.Owin.Security.OpenIdConnect中间件,默认登出流程不会自动传递id_token_hint参数给Duende IdentityServer。而IdentityServer需要这个参数关联用户会话、识别客户端,才能填充LogoutContext里的ClientId、ClientName、PostLogoutRedirectUri等属性。缺少该参数时,IdentityServer无法定位对应客户端信息,这些属性自然为空。
另外,你的客户端登出代码仅调用SignOut并清除Cookie,没有正确触发OIDC协议的前端登出流程,导致必要参数未携带到IdentityServer。
解决方案
1. 配置OIDC登出通知,传递id_token_hint
在客户端的OpenIdConnectAuthenticationOptions的Notifications中添加RedirectToIdentityProviderForSignOut处理逻辑,从已保存的令牌中取出id_token并作为参数传递:
Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async context => { var identity = context.AuthenticationTicket.Identity; var claims = identity.Claims; await Task.Yield(); }, // 新增登出时的参数传递逻辑 RedirectToIdentityProviderForSignOut = async context => { // 从用户Claims中获取保存的id_token var idToken = context.OwinContext.Authentication.User.FindFirst("id_token")?.Value; if (!string.IsNullOrEmpty(idToken)) { context.ProtocolMessage.IdTokenHint = idToken; } // 显式传递PostLogoutRedirectUri context.ProtocolMessage.PostLogoutRedirectUri = context.Options.PostLogoutRedirectUri; await Task.Yield(); } }
2. 修改客户端登出代码,正确触发OIDC登出流程
调整登出代码,确保OIDC中间件能发起完整的登出请求到IdentityServer:
// 清除自定义Cookie HttpCookie userCookie = new HttpCookie("UserCookie", ""); userCookie.Expires = DateTime.Now.AddYears(-1); Response.Cookies.Add(userCookie); // 配置登出属性,触发OIDC流程 var properties = new AuthenticationProperties { RedirectUri = "https://localhost:5002" // 可选,登出完成后的跳转地址 }; HttpContext.GetOwinContext().Authentication.SignOut(properties, OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); return new EmptyResult(); // 返回EmptyResult确保流程正常执行,不要返回null
3. 验证IdentityServer客户端配置
确保Duende IdentityServer的客户端配置中,PostLogoutRedirectUris包含客户端配置的PostLogoutRedirectUri值:
// IdentityServer端客户端配置示例 new Client { ClientId = "SomeId", ClientSecrets = { new Secret("SomeSecret".Sha256()) }, AllowedGrantTypes = GrantTypes.Code, RedirectUris = { "https://localhost:5002" }, PostLogoutRedirectUris = { "https://localhost:5002/some-custom-path" }, // 必须与客户端配置一致 AllowedScopes = { "SomeScopes" } }
验证逻辑
完成修改后,登出时客户端会向IdentityServer发起包含id_token_hint和post_logout_redirect_uri参数的请求,IdentityServer可通过id_token_hint定位客户端会话,从而正确填充LogoutContext的各项属性。
内容的提问来源于stack exchange,提问作者Bryan Baan

