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

.NET Core 5 Web API适配企业API网关:自定义JWT授权请求头及前端适配问题咨询

我来帮你一步步解决这个问题,分为后端API配置和前端React+MSAL适配两部分:

后端.NET Core 5 Web API配置修改

你需要调整JWT Bearer认证的令牌获取逻辑,让它从自定义的MyApp-Authorization头中提取应用自身的JWT令牌,而不是默认的Authorization头。具体修改如下:

在你的ConfigureServices方法中,找到AddJwtBearer的配置块,添加Events来指定令牌来源:

public void ConfigureServices(IServiceCollection services) {
    //...
    //Add ASP.NET Core Identity Services
    services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<RPToolDBContext>()
        .AddSignInManager<SignInManager<IdentityUser>>();
    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Secret));
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(opt => {
            opt.TokenValidationParameters = new TokenValidationParameters {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = key,
                ValidateAudience = false,
                ValidateIssuer = false,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            };
            // 新增:从自定义头获取JWT令牌
            opt.Events = new JwtBearerEvents
            {
                OnMessageReceived = context =>
                {
                    // 读取MyApp-Authorization头,提取Bearer令牌
                    var tokenHeader = context.Request.Headers["MyApp-Authorization"].FirstOrDefault();
                    if (!string.IsNullOrEmpty(tokenHeader) && tokenHeader.StartsWith("Bearer "))
                    {
                        context.Token = tokenHeader.Substring(7); // 去掉"Bearer "前缀
                    }
                    return Task.CompletedTask;
                }
            };
        })
        .AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));
    //...
    // 确保授权策略使用正确的认证方案
    services.AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser()
            .Build();
    });
}

这样配置后,你的API就会优先从MyApp-Authorization头读取自身的JWT令牌,而网关的Authorization头会由网关自行验证,你的应用不需要处理它。

前端React+MSAL适配修改

是的,前端需要修改代码来适配这个新的请求头格式。因为MSAL默认会将获取到的令牌放在Authorization头中,现在你需要发送两个令牌:一个给网关(放在Authorization头),另一个给你的应用(放在MyApp-Authorization头)。

核心实现示例(基于@azure/msal-react和axios):

import { useMsal } from "@azure/msal-react";
import { InteractionRequiredAuthError } from "@azure/msal-browser";
import axios from "axios";

// 获取网关所需的令牌
const getGatewayToken = async (msalInstance) => {
  const gatewayRequest = {
    scopes: ["api://your-gateway-client-id/.default"] // 替换为网关的API范围
  };
  try {
    // 静默获取令牌
    const response = await msalInstance.acquireTokenSilent(gatewayRequest);
    return response.accessToken;
  } catch (error) {
    // 静默失败则弹出登录窗口
    if (error instanceof InteractionRequiredAuthError) {
      const response = await msalInstance.acquireTokenPopup(gatewayRequest);
      return response.accessToken;
    }
    throw error;
  }
};

// 获取应用自身所需的令牌
const getAppToken = async (msalInstance) => {
  const appRequest = {
    scopes: ["api://your-app-client-id/.default"] // 替换为你的API范围
  };
  try {
    const response = await msalInstance.acquireTokenSilent(appRequest);
    return response.accessToken;
  } catch (error) {
    if (error instanceof InteractionRequiredAuthError) {
      const response = await msalInstance.acquireTokenPopup(appRequest);
      return response.accessToken;
    }
    throw error;
  }
};

// 配置axios请求拦截器
const setupAxiosInterceptors = () => {
  const { instance } = useMsal();
  axios.interceptors.request.use(async (config) => {
    // 获取两个令牌
    const gatewayToken = await getGatewayToken(instance);
    const appToken = await getAppToken(instance);
    
    // 添加请求头
    config.headers["Authorization"] = `Bearer ${gatewayToken}`;
    config.headers["MyApp-Authorization"] = `Bearer ${appToken}`;
    
    return config;
  }, (error) => {
    return Promise.reject(error);
  });
};

// 在应用初始化时调用拦截器配置
setupAxiosInterceptors();

注意事项:

  • 确保网关和应用的令牌请求使用正确的clientId和scopes,否则会获取到无效令牌
  • 处理令牌过期、静默获取失败等异常情况,提升用户体验
  • 如果你的应用和网关使用同一身份提供商(比如Azure AD),可能需要调整令牌获取的参数来区分不同的受众

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 14:58:11