OpenID Connect登出后重定向功能失效问题求助
问题:Blazor Server OIDC登出后跳转到空白页面及sid参数缺失报错
我正在构建基于Blazor Server的ASP.NET Core应用,采用OpenID Connect(OIDC)提供商的Cookie认证。登出时希望重定向到已在OIDC提供商注册为Post Logout Redirect URI的本地地址:https://localhost:44378/signout-oidc。
执行登出流程时,OIDC提供商日志显示“End session request validation success”,但最终跳转到带state参数的https://localhost:44378/signout-oidc?state=CfDJ8LdQ[...]空白页面。若登录状态下访问该地址,会报错:
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Error: The remote signout request was ignored because the 'sid' parameter was missing, which may indicate an unsolicited logout。
我尝试过调整SignedOutRedirectUri、SignedOutCallbackPath、RemoteSignOutPath等参数,以及重定向到其他页面,但均无效,恳请提供解决思路。
当前配置代码
认证配置代码
services.AddAuthentication(opt => { opt.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; opt.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; opt.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }).AddCookie("Cookies", options => { options.Cookie.SameSite = SameSiteMode.None; }) .AddOpenIdConnect("oidc", options => { options.Authority = configuration.GetSection("AuthorizationStrings")["Authority"]; options.ClientId = configuration.GetSection("AuthorizationStrings")["ClientId"]; options.ClientSecret = configuration.GetSection("AuthorizationStrings")["ClientSecret"]; options.ResponseType = "code"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; options.UseTokenLifetime = false; options.Scope.Add("openid"); options.Scope.Add("profile"); options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name" }; options.SignedOutCallbackPath = "/signout-oidc"; });
登出流程代码
public async Task OnGetAsync() { var ac = await HttpContext.GetTokenAsync("access_token"); String uri = String.Format("[CONNECT PROVIDER URI]/endsession?id_token_hint={0}&post_logout_redirect_uri=https://localhost:44378/signout-oidc", ac); await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); var prop = new AuthenticationProperties { RedirectUri = uri }; await HttpContext.SignOutAsync("oidc", prop); }
解决思路
1. 修正登出流程的顺序与参数问题
- 不要手动拼接OIDC登出URI:
SignOutAsync("oidc")会自动处理向OIDC提供商发起登出请求的逻辑,手动拼接URI会绕过ASP.NET Core OIDC中间件的state验证流程,导致回调时state不匹配或缺失必要参数(如sid)。 - 调整登出顺序与逻辑:直接调用OIDC的SignOutAsync,中间件会自动处理本地Cookie登出+向OIDC提供商发起登出请求:
public async Task OnGetAsync() { var props = new AuthenticationProperties { RedirectUri = "/" // 设置登出完成后最终跳转的页面,比如首页 }; await HttpContext.SignOutAsync("oidc", props); // 无需单独调用Cookie的SignOutAsync,OIDC中间件会自动处理 } - 替换id_token_hint的来源:OIDC规范中
id_token_hint需要传入id_token而非access_token,这是常见错误,修改获取代码:var idToken = await HttpContext.GetTokenAsync("id_token");
2. 完善OIDC中间件配置
- 配置SignedOutRedirectUri:指定OIDC登出回调完成后最终跳转的页面,避免停留在空白的signout-oidc页面:
options.SignedOutRedirectUri = "/"; // 跳转到首页或指定页面 - 确保sid Claim被保留:sid(Session ID)是OIDC提供商识别用户会话的关键参数,需确保中间件正确获取并保留该Claim:
options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", SaveSigninToken = true, // 避免过滤掉sid Claim ClaimFilter = null }; - 配置远程登出事件处理:如果OIDC提供商支持主动登出,添加事件处理逻辑,确保回调后能正确跳转:
options.Events = new OpenIdConnectEvents { OnRemoteSignOut = context => { context.Response.Redirect("/"); context.HandleResponse(); return Task.CompletedTask; } };
3. 验证OIDC提供商配置
- 确认Post Logout Redirect URI已在OIDC提供商后台正确注册,且与代码中
SignedOutCallbackPath或跳转地址完全一致(包括HTTPS端口)。 - 检查OIDC提供商是否强制要求登出请求包含state参数,即使文档标注“可选”,部分提供商仍会验证state有效性,手动拼接URI时未生成有效state会导致回调验证失败。
内容的提问来源于stack exchange,提问作者KDA
相关产品推荐
相关产品推荐

