如何在Duende IdentityServer v6.2.3与Asp.Net Core 6.0 MVC中获取注销端点的id_token
解决方案:获取id_token并完成IdentityServer注销
问题根源
你当前使用的是纯authorization_code授权流(ResponseType为code),这种模式下IdentityServer不会返回id_token——只有切换到混合流(Hybrid Flow),才能同时获取授权码和id_token。之前修改ResponseType为code id_token报错,是因为IdentityServer端的客户端配置未启用混合流支持。
步骤1:更新IdentityServer客户端配置
在IdentityServer的客户端定义中,修改以下配置:
- 将
AllowedGrantTypes设置为GrantTypes.Hybrid(混合流支持授权码+id_token的组合) - 确保
AllowedScopes包含openid(这是生成id_token的必要Scope)
示例代码:
new Client { ClientId = "your-mvc-client-id", ClientName = "MVC客户端", AllowedGrantTypes = GrantTypes.Hybrid, // 切换为混合流 ClientSecrets = { new Secret("your-client-secret".Sha256()) }, RedirectUris = { "https://your-mvc-app.com/signin-oidc" }, PostLogoutRedirectUris = { "https://your-mvc-app.com/signout-callback-oidc" }, AllowedScopes = { "openid", "profile", "your-api-scopes" }, // 必须包含openid RequirePkce = true, // 公共客户端建议开启,机密客户端可选 RequireConsent = false }
步骤2:更新MVC应用的OpenIdConnect配置
在Program.cs中调整认证服务配置:
- 设置
ResponseType = "code id_token" - 开启
SaveTokens = true,确保id_token被保存到认证会话中
示例代码:
builder.Services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.Authority = "https://your-identityserver-url"; options.ClientId = "your-mvc-client-id"; options.ClientSecret = "your-client-secret"; options.ResponseType = "code id_token"; // 混合流响应类型 options.SaveTokens = true; // 保存令牌到会话 options.Scope.Add("openid"); options.Scope.Add("profile"); // 其他自定义配置... });
步骤3:获取id_token并发起注销
在MVC的Logout动作中,可以通过HttpContext直接获取保存的id_token,用于构造注销请求:
public async Task<IActionResult> Logout() { // 从会话中获取id_token var idToken = await HttpContext.GetTokenAsync("id_token"); // 自动触发IdentityServer注销流程 return SignOut( new AuthenticationProperties { RedirectUri = "/" }, "Cookies", "oidc"); }
如果需要手动构造注销链接:
var logoutUrl = $"{options.Authority}/connect/endsession?id_token_hint={idToken}&post_logout_redirect_uri={Uri.EscapeDataString("https://your-mvc-app.com")}"; return Redirect(logoutUrl);
内容的提问来源于stack exchange,提问作者doogdeb
相关产品推荐
相关产品推荐

