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

Azure上API与Blazor WebAssembly通信异常:多余Cookie问题求助

Azure部署后Blazor WASM与.NET Core API通信中断问题

问题详情

  • 部署环境:Azure上托管的.NET Core API + Blazor WebAssembly应用
  • 异常现象:二者通信中断,请求中出现非预期的ARRAffinity Cookie,应用仅应使用.AspNetCore.Identity.Application Cookie
  • 对比场景:
    • 本地开发环境通信正常,仅存在预期Cookie
    • PostMan/Swagger直接调用API无异常,仅Blazor应用发起调用时出现问题

WebAssembly端program.cs代码

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
 
builder.Services.AddRadzenComponents();

builder.Services.AddScoped<CookieHandler>();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, AuthAPI>();
builder.Services.AddScoped<AuthAPI>(sp => (AuthAPI)sp.GetRequiredService<AuthenticationStateProvider>());
builder.Services.AddCascadingAuthenticationState();
 
builder.Services.AddScoped<Status>();
  
builder.Services.AddHttpClient("API", client => {
    client.BaseAddress = new Uri(builder.Configuration["API:Url"]!);
    //  client.BaseAddress = new Uri("https://localhost:7089/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AddHttpMessageHandler<CookieHandler>();

await builder.Build().RunAsync();

API端代码

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddDbContext<HContext>((options) =>
{
    options
            .UseSqlServer(builder.Configuration["ConnectionStrings:HDB"])
            .UseLazyLoadingProxies();
});

void UseLazyLoadingProxies()
{
    throw new NotImplementedException();
}

builder.Services
    .AddIdentityApiEndpoints<IdentityUser>()
    .AddEntityFrameworkStores<Context>();

builder.Services.AddAuthentication();

builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen();

builder.Services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(options => options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);

builder.Services.AddCors(
    options => options.AddPolicy(
        "wasm",
        policy => policy
            .AllowAnyMethod()
            .SetIsOriginAllowed(pol => true)
            .AllowAnyHeader()
            .AllowCredentials()));

builder.Services.ConfigureApplicationCookie(options => { 
    options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.None; options.Cookie.Name = ".AspNetCore.Identity.Application"; options.LoginPath = "/login"; options.LogoutPath = "/Identity/Logout"; options.AccessDeniedPath = "/"; });


var app = builder.Build();

app.UseHttpsRedirection();

app.UseCors("wasm");

app.UseStaticFiles();

app.UseCookiePolicy();

app.UseAuthorization();

app.MapCustomIdentityApi<IdentityUser>();

app.MapControllers();

app.UseSwagger();

app.UseSwaggerUI();

app.UseMiddleware<ReadMe.Metrics>();

app.Run();

排查与解决思路

1. 明确ARRAffinity Cookie的来源

ARRAffinity是Azure App Service自动添加的应用服务亲和性Cookie,用于多实例部署时将用户请求固定到同一实例。本地环境无多实例架构,因此不会生成该Cookie。

2. 问题触发原因

Blazor WASM的HttpClient会自动携带当前域名下的所有Cookie,而PostMan/Swagger等独立工具不会自动传递无关Cookie。核心问题在于:

  • CORS配置未限制Cookie传递范围
  • Blazor端的CookieHandler未过滤非预期Cookie

3. 具体解决方案

方案1:禁用Azure App Service的ARR亲和性

在Azure门户操作:

  • 进入API所在的App Service
  • 打开配置 > 常规设置
  • 关闭ARR亲和性开关
  • 保存后重启服务

方案2:在Blazor端过滤非预期Cookie

修改CookieHandler,发送请求前移除ARRAffinity及ARRAffinitySameSite Cookie:

public class CookieHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // 筛选需要保留的Cookie
        var validCookies = request.Headers.GetCookies()
            .SelectMany(c => c.Cookies)
            .Where(c => c.Name.Equals(".AspNetCore.Identity.Application", StringComparison.OrdinalIgnoreCase))
            .Select(c => $"{c.Name}={c.Value}");

        // 重置Cookie头
        request.Headers.Remove("Cookie");
        if (validCookies.Any())
        {
            request.Headers.Add("Cookie", string.Join("; ", validCookies));
        }

        return await base.SendAsync(request, cancellationToken);
    }
}

方案3:优化API端CORS配置(生产环境建议)

替换宽松的来源配置为具体Blazor应用域名,避免不必要的凭证传递:

builder.Services.AddCors(options => options.AddPolicy("wasm", policy => policy
    .WithOrigins("https://your-blazor-app.azurewebsites.net") // 替换为实际Blazor域名
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials()));

4. 验证步骤

  1. 部署修改后的代码到Azure
  2. 打开Blazor应用,通过浏览器开发者工具(F12)查看Network面板
  3. 确认API请求的Cookie仅包含.AspNetCore.Identity.Application
  4. 测试API调用是否恢复正常

内容的提问来源于stack exchange,提问作者Fabio Cardoso Nobre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:45:15