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

Blazor中使用IHttpClientFactory添加Cookie:登录后Header Propagation失效问题

问题:Blazor项目中Header Propagation登录后未更新Cookie令牌

场景描述

我有一个依赖外部API的Blazor项目,登录时调用API获取会话令牌并存储到Claim中,要求该令牌以Cookie形式随每次请求发送。我采用Header Propagation结合IHttpClientFactory实现,配置代码如下:

services.AddHttpClient<ServiceClient>(client =>
{
    client.BaseAddress = new Uri(url);
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
})
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()
{
    ClientCertificateOptions = ClientCertificateOption.Manual,
    ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => { return true; },
})
.AddHeaderPropagation(options =>
{
    options.Headers.Add("Cookie");
});

services.AddHeaderPropagation(options =>
    options.Headers.Add("Cookie", context =>
    {
        var identity = context.HttpContext.User.Identities.FirstOrDefault(x => x.AuthenticationType == "AppAuthenticationType");
        if (identity?.IsAuthenticated ?? false)
            return $"SESSION={identity.GetSession()}";
        return String.Empty;
    });

中间件配置在app.UseAuthentication();和app.UseAuthorization();之后添加了app.UseHeaderPropagation();。

遇到的问题:首次打开网站未登录时Claim未设置;登录后设置了Claim,但Header Propagation未更新,令牌未随请求发送。

解决方案

1. 移除重复的Header Propagation配置

你的代码中存在两处AddHeaderPropagation配置:一处在HttpClient注册时添加了默认的Cookie头,另一处全局配置了自定义的Cookie头生成逻辑。这会导致头信息的生成逻辑冲突,且默认配置不会动态更新用户认证状态。

删除HttpClient注册中的AddHeaderPropagation(options => options.Headers.Add("Cookie")),仅保留全局的自定义配置,确保每次请求都执行委托获取当前用户的令牌:

services.AddHttpClient<ServiceClient>(client =>
{
    client.BaseAddress = new Uri(url);
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
})
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()
{
    ClientCertificateOptions = ClientCertificateOption.Manual,
    ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true,
})
.AddHeaderPropagation(); // 仅启用Header Propagation,不再指定默认Cookie头

services.AddHeaderPropagation(options =>
{
    options.Headers.Add("Cookie", context =>
    {
        var identity = context.HttpContext.User.Identities.FirstOrDefault(x => x.AuthenticationType == "AppAuthenticationType");
        if (identity?.IsAuthenticated ?? false)
        {
            // 确保GetSession()方法正确从Claim中提取令牌,这里可以显式写出Claim类型避免歧义
            var sessionToken = identity.Claims.FirstOrDefault(c => c.Type == "SessionToken")?.Value;
            return !string.IsNullOrEmpty(sessionToken) ? $"SESSION={sessionToken}" : string.Empty;
        }
        return string.Empty;
    });
});

2. 确认中间件顺序正确性

确保UseHeaderPropagation的位置在UseAuthentication和UseAuthorization之后,且在UseRouting和UseEndpoints之前,这样中间件才能获取到经过认证的用户上下文:

app.UseAuthentication();
app.UseAuthorization();
app.UseHeaderPropagation();

app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});

3. 验证Claim提取逻辑

确保GetSession()扩展方法(或显式的Claim提取逻辑)能正确从用户Identity中获取会话令牌。建议显式指定Claim类型,避免因Claim名称不匹配导致令牌无法获取。

4. Blazor Server额外注意事项

在Blazor Server中,确保ServiceClient是通过依赖注入获取的Scoped服务(默认AddHttpClient注册的客户端是Transient,但底层的HttpMessageHandler是池化的,HeaderPropagationHandler会在每次请求时从当前HttpContext获取头信息)。组件中调用API时,直接注入ServiceClient即可保证使用当前用户的上下文。

内容的提问来源于stack exchange,提问作者Antonio Rodríguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:40:30