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

React v18应用集成Azure AD与数据库登录及JWT授权问题求助

解决方案与方向验证

方向正确性确认

你的方案方向完全没问题:两种登录方式分别对接不同身份源,统一通过JWT在API端做授权,是前后端分离架构下多身份认证的标准实现路径。

分步骤整合方案

1. 后端JWT统一输出逻辑

不管是数据库登录还是Azure AD登录,后端必须输出结构一致、签名规则统一的JWT Token,这样API授权逻辑只需要一套校验规则:

  • 数据库登录流程:
    1. 前端提交用户名密码到Web API
    2. API验证SQL Server内的用户凭证,通过后用同一套密钥/签名算法生成JWT,Payload里要包含用户ID、角色、登录类型(比如"auth_type": "database")等必要字段
    3. 把Token返回给前端
  • Azure AD登录流程:
    1. 前端用MSAL.js完成Azure AD授权,拿到AD颁发的Token
    2. 前端把AD Token传给Web API的Token交换接口
    3. API验证AD Token合法性(校验签名、issuer、audience等,可调用Azure AD公钥端点验证)
    4. 验证通过后,生成自有系统的JWT(和数据库登录生成的Token结构、签名完全一致),Payload里要包含关联后的系统用户ID(需提前把AD用户和SQL Server内的系统用户绑定,比如通过AD的邮箱/oid字段)、角色、登录类型("auth_type": "azure_ad")
    5. 返回自有JWT给前端

2. API端统一授权中间件

写一个全局JWT验证中间件,只校验Token的签名、有效期、核心Payload字段,不用区分登录来源:

// .NET Web API中间件核心示例
public async Task InvokeAsync(HttpContext context)
{
    var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
    if (token == null)
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return;
    }

    try
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(Configuration["Jwt:Secret"]);
        tokenHandler.ValidateToken(token, new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidateAudience = true,
            ValidAudience = Configuration["Jwt:Audience"],
            ClockSkew = TimeSpan.Zero
        }, out SecurityToken validatedToken);

        var jwtToken = (JwtSecurityToken)validatedToken;
        var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "user_id").Value);
        var authType = jwtToken.Claims.First(x => x.Type == "auth_type").Value;

        // 将用户信息存入HttpContext,供后续接口使用
        context.Items["CurrentUser"] = new { Id = userId, AuthType = authType };
        await _next(context);
    }
    catch
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
    }
}

3. 前端状态统一管理

React端用状态管理工具(Redux、Zustand或Context API都行)统一维护登录状态和Token:

  • 数据库登录:提交表单后,接收API返回的Token,存入localStorage/sessionStorage和状态,再跳转首页
  • Azure AD登录:通过MSAL.js拿到AD Token后,调用后端Token交换接口,拿到自有JWT,同样存入存储和状态,再跳转首页
  • 路由守卫:所有需要授权的页面,检查状态里有没有有效Token,没有就跳登录页

4. 数据库登录后无法打开首页的排查点

  • 检查登录成功后的跳转逻辑:是不是正确调用了路由跳转方法(比如navigate("/")),有没有路由守卫错误拦截(比如守卫逻辑误判Token无效)
  • 检查Token存储:确认数据库登录返回的Token已经正确存入存储,路由守卫能读取到
  • 检查首页接口请求:如果首页需要调用API,确认请求头里已经带上Authorization: Bearer {token},且API端验证通过

关键注意事项

  • 别直接用Azure AD的Token做自有API授权:AD Token的受众是Azure服务,用自有JWT更灵活,还能避免依赖AD服务的可用性
  • 两种登录生成的JWT必须用同一套签名密钥和算法,否则中间件没法统一校验
  • 提前在SQL Server里完成Azure AD用户和系统用户的关联(比如通过AD的邮箱或oid字段绑定)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:41:34