You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:35:22