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

.NET 8 Blazor Server 2FA用户40分钟后断开及防伪令牌解密失败问题

解决Blazor Server 2FA用户40分钟后登录断开及Antiforgery报错问题

1. 显式配置Antiforgery Cookie有效期

Antiforgery令牌解密失败的核心原因是其关联Cookie默认有效期较短(与会话绑定),需单独配置与登录Cookie一致的30天有效期:

builder.Services.AddAntiforgery(options =>
{
    options.Cookie.Name = ".AspNetCore.Antiforgery";
    options.Cookie.Expiration = TimeSpan.FromDays(30);
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境建议启用HTTPS
    options.Cookie.SameSite = SameSiteMode.Lax;
});

2. 调整Blazor Server Circuit超时时间

Blazor Server默认Circuit超时为30分钟,超时后Circuit断开,重新交互时易触发Antiforgery验证失败,需延长Circuit相关配置:

builder.Services.AddServerSideBlazor(options =>
{
    options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromDays(1); // 保留断开的Circuit 1天
    options.CircuitOptions.MaxRetainedCircuits = 100; // 根据服务器并发量调整
});

同时在_Host.cshtml中配置SignalR连接超时:

<script src="_framework/blazor.server.js"></script>
<script>
    Blazor.start({
        configureSignalR: function (builder) {
            builder.withUrl("/_blazor", {
                skipNegotiation: true,
                transport: signalR.HttpTransportType.WebSockets,
                timeout: 300000 // 设置为5分钟超时,按需调整
            });
        }
    });
</script>

3. 统一认证票据与Cookie配置

仅配置ApplicationCookie不够,需确保登录生成的认证票据有效期与Cookie对齐,同时覆盖外部OAuth登录的Cookie逻辑:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromDays(30);
    options.SlidingExpiration = true;
    options.LoginPath = "/Login";
    // 确保票据有效期与Cookie同步
    options.Events = new CookieAuthenticationEvents
    {
        OnSigningIn = context =>
        {
            context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(30);
            context.Properties.IsPersistent = true;
            return Task.CompletedTask;
        }
    };
})
.AddGoogle(options =>
{
    // 填入你的Google OAuth配置
    options.ClientId = "your-client-id";
    options.ClientSecret = "your-client-secret";
    // 复用主登录Cookie,避免外部登录Cookie单独过期
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});

4. 2FA验证后更新票据有效期

如果使用自定义2FA验证逻辑,需确保验证通过后生成的认证票据使用30天有效期:

// 示例:2FA验证通过后的登录代码
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
    ExpiresUtc = DateTimeOffset.UtcNow.AddDays(30),
    IsPersistent = true,
    AllowRefresh = true // 支持滑动过期刷新
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);

5. 配置心跳机制维持滑动过期

滑动过期需要用户主动交互才会刷新Cookie,若用户长时间无操作,可在主布局中添加定时心跳:

@implements IDisposable

@code {
    private Timer _heartbeatTimer;

    protected override void OnInitialized()
    {
        // 每30分钟发送一次心跳请求,触发Cookie刷新
        _heartbeatTimer = new Timer(async _ =>
        {
            await Http.GetAsync("/api/heartbeat");
        }, null, TimeSpan.Zero, TimeSpan.FromMinutes(30));
    }

    public void Dispose()
    {
        _heartbeatTimer?.Dispose();
    }
}

同时添加对应的心跳API:

[ApiController]
[Route("api/[controller]")]
public class HeartbeatController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok();
    }
}

内容的提问来源于stack exchange,提问作者Christoff Colomb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:36:04