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

使用Blazor InteractiveAuto与Microsoft Entra时GraphQL认证调用失败

Blazor InteractiveAuto模式下GraphQL授权问题修复方案

问题复盘

在Blazor InteractiveAuto模式下配置服务器端GraphQL客户端,未添加授权时功能正常,但启用必填授权后,系统未使用已存在的.AspNetCore.Cookies进行认证,反而触发OIDC重定向;更异常的是,端点返回404而非预期的400未授权状态。已通过Nitro工具验证:登录状态下无需额外配置即可访问认证端点(工具会自动传递Cookie),但注销状态下同样收到404。

核心问题

  1. 默认认证方案为OIDC,即使GraphQL端点指定Cookie方案,中间件仍优先触发OIDC的重定向逻辑
  2. 手动创建的CookieContainer是全新实例,未复用当前用户的认证Cookie,导致请求无有效凭证
  3. GraphQL端点路由或授权配置模糊,引发404路由匹配错误

分步修复

1. 调整认证方案默认配置

将Cookie设为默认认证方案,同时保留OIDC用于登录流程:

// 注册认证服务,设置Cookie为默认方案
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie()
    .AddMicrosoftIdentityWebApp(
        builder.Configuration.GetSection("AzureAd"),
        openIdConnectScheme: OpenIdConnectDefaults.AuthenticationScheme,
        cookieScheme: CookieAuthenticationDefaults.AuthenticationScheme);

2. 让GraphQL客户端复用当前请求的Cookie

手动创建的CookieContainer不会包含用户的认证Cookie,需要从当前HttpContext中获取并复用:

// 先注册HttpContextAccessor
builder.Services.AddHttpContextAccessor();

// 配置GraphQL客户端
builder.Services.AddScoped(sp =>
{
    var httpContextAccessor = sp.GetRequiredService<IHttpContextAccessor>();
    var navigationManager = sp.GetRequiredService<NavigationManager>();
    var baseUri = new Uri(navigationManager.BaseUri);

    var handler = new HttpClientHandler
    {
        UseCookies = true,
        CookieContainer = httpContextAccessor.HttpContext?.Request.Cookies.ToCookieContainer(baseUri)
    };

    return new GraphQLHttpClient(config =>
    {
        config.EndPoint = new Uri($"{navigationManager.BaseUri}graphql");
        config.HttpMessageHandler = handler;
    }, new SystemTextJsonSerializer());
});

// 扩展方法:将RequestCookies转换为CookieContainer
public static CookieContainer ToCookieContainer(this IRequestCookieCollection cookies, Uri baseUri)
{
    var container = new CookieContainer();
    if (cookies == null) return container;
    
    foreach (var cookie in cookies)
    {
        container.Add(new Cookie(cookie.Key, cookie.Value, "/", baseUri.Host));
    }
    return container;
}

3. 修正GraphQL端点的授权与路由配置

明确指定GraphQL路径,并创建专属授权策略,避免路由模糊匹配导致404:

// 配置GraphQL端点,指定路径并绑定专属授权策略
app.MapGraphQL("/graphql")
   .RequireAuthorization(options =>
   {
       options.AddPolicy("GraphQLCookieAuth", policy =>
       {
           policy.AuthenticationSchemes.Add(CookieAuthenticationDefaults.AuthenticationScheme);
           policy.RequireAuthenticatedUser();
       });
   });

4. 禁用API请求的OIDC自动重定向

对GraphQL这类API请求,直接返回401而非重定向到登录页:

.AddMicrosoftIdentityWebApp(
    builder.Configuration.GetSection("AzureAd"),
    openIdConnectScheme: OpenIdConnectDefaults.AuthenticationScheme,
    cookieScheme: CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(options =>
{
    options.Events = new OpenIdConnectEvents
    {
        OnRedirectToIdentityProvider = context =>
        {
            // 拦截GraphQL请求,返回401而非重定向
            if (context.Request.Path.StartsWithSegments("/graphql"))
            {
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                context.HandleResponse();
            }
            return Task.CompletedTask;
        }
    };
});

验证步骤

  • 登录后检查浏览器网络请求,确认GraphQL请求头包含.AspNetCore.Cookies Cookie
  • 注销状态下访问GraphQL端点,应返回401而非404
  • 用Nitro工具再次测试,确保端点路由与授权逻辑正常

内容的提问来源于stack exchange,提问作者Evan Kaiser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:03:13