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

Blazor Server使用OpenIdConnect时AccessToken为空问题求助

Blazor Server 认证Cookie异常问题

我有一个Blazor Server端应用,最初基于.NET5创建,当前目标框架为.NET8(未使用.NET8特有功能),遇到了认证相关的异常问题,以下是详细配置和现象:

服务配置

Startup.cs中配置了自定义的Cookie存储:

services.AddSingleton<ITicketStore, CookieMemoryTicketStore>();
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
        .Configure<ITicketStore>((options, store) =>
        {
            options.ExpireTimeSpan = TimeSpan.FromDays(14);
            options.SlidingExpiration = true;
            options.SessionStore = store;
        });

认证授权配置

认证部分采用Cookie认证+OpenID Connect:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Authority = "authority";
    options.ClientId = "clientid";
    options.ClientSecret = "clientsecret";
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.ResponseMode = OpenIdConnectResponseMode.FormPost;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.MapInboundClaims = false;
    options.SaveTokens = true;
    options.UseTokenLifetime = false;
    options.UseSecurityTokenValidator = true;
    options.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    options.Scope.Add(OpenIdConnectScope.Email);
    options.Scope.Add(OpenIdConnectScope.OfflineAccess);
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "role"
    };
});
services.AddAuthorizationCore();

初始状态获取

在_Host.cshtml中获取令牌并传入应用:

var tokens = new InitialApplicationState
{
    AccessToken = await HttpContext.GetTokenAsync(Token.Access),
    IdToken = await HttpContext.GetTokenAsync(Token.Id),
    RefreshToken = await HttpContext.GetTokenAsync(Token.Refresh),
};

InitialApplicationState随后在App.razor中使用。

登录流程代码

从认证提供者重定向回来时,调用用户信息接口:

var oidcOptions = new OidcClientOptions
{
    Authority = "issuer",
    ClientId = "clientid",
    LoadProfile = false,
    Scope = StandardScopes.OpenId
};

var client = new OidcClient(oidcOptions);
var state = await client.GetUserInfoAsync(tokenProvider.AccessToken, ct);

问题现象

  • 应用运行数小时内正常,但之后用户通过浏览器中存储的认证Cookie自动认证时,GetUserInfoAsync调用因tokenProvider.AccessToken为null而失败,唯一解决方法是删除站点所有Cookie,认证授权恢复正常。
  • 更新排查:在_Host.cshtml中执行await HttpContext.AuthenticateAsync()返回Failure,提示信息为Unprotect ticket failed,页面进入无限刷新循环。
  • 已添加Cookie事件,确认登录时Properties中包含正确的access和refresh token:
options.Events.OnSignedIn = context =>
{
    context.Properties.IsPersistent = true;
    return Task.CompletedTask;
};

是否有人遇到过这个问题?上述代码是否缺少某些必要步骤?

内容的提问来源于stack exchange,提问作者Ivan Debono

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:24:51