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

ASP.NET Core多服务共享JWT Token授权问题咨询

当然可以!JwtBearer认证方案正是为这类跨API授权场景设计的——它能让API B可靠验证API A签发的JWT令牌,实现安全的跨服务访问控制。下面我一步步给你讲具体怎么配置:

一、API A(令牌签发方)的配置

API A的核心是生成符合规范的JWT令牌,需要先配置JWT的基础参数,再实现登录接口生成令牌。

  1. 配置JWT服务
    在Program.cs中添加认证服务,并配置JWT的验证参数(这些参数会被用来生成合法的令牌):
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// 添加JWT认证服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            // 这些参数要和API B保持完全一致
            ValidIssuer = builder.Configuration["Jwt:Issuer"], // 示例:"https://apia.example.com"
            ValidAudience = builder.Configuration["Jwt:Audience"], // 示例:"https://apib.example.com"
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) // 加密密钥,建议用复杂字符串
        };
    });

// 添加控制器服务
builder.Services.AddControllers();

var app = builder.Build();

// 启用认证中间件
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();
  1. 实现登录接口生成令牌
    创建一个登录接口,验证用户账号密码后生成JWT返回给客户端:
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
    private readonly IConfiguration _configuration;
    private readonly IUserService _userService; // 假设你有自定义的用户验证服务

    public AuthController(IConfiguration configuration, IUserService userService)
    {
        _configuration = configuration;
        _userService = userService;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginRequest request)
    {
        // 第一步:验证用户账号密码合法性
        var validUser = _userService.ValidateCredentials(request.Username, request.Password);
        if (validUser == null)
        {
            return Unauthorized("账号或密码错误");
        }

        // 第二步:构造JWT的Claims(自定义用户信息,比如用户名、角色)
        var claims = new List<Claim>
        {
            new Claim(JwtRegisteredClaimNames.Sub, validUser.Username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(ClaimTypes.Role, validUser.Role) // 示例:添加角色权限Claim
        };

        // 第三步:生成JWT令牌
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
        var signingCreds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: _configuration["Jwt:Issuer"],
            audience: _configuration["Jwt:Audience"],
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(30), // 设置令牌过期时间
            signingCredentials: signingCreds);

        // 返回令牌给客户端
        return Ok(new
        {
            AccessToken = new JwtSecurityTokenHandler().WriteToken(token),
            ExpiresAt = token.ValidTo
        });
    }
}

// 登录请求模型
public class LoginRequest
{
    public string Username { get; set; }
    public string Password { get; set; }
}
二、API B(资源服务方)的配置

API B需要配置JwtBearer来验证API A签发的令牌,核心是和API A使用完全一致的JWT参数。

  1. 配置JWT认证与授权
    在Program.cs中添加认证和授权服务:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// 添加JWT认证服务,参数必须和API A完全匹配!
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"], // 和API A一致
            ValidAudience = builder.Configuration["Jwt:Audience"], // 和API A一致
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) // 和API A一致
        };
    });

// 添加授权服务
builder.Services.AddAuthorization();

// 添加控制器服务
builder.Services.AddControllers();

var app = builder.Build();

// 中间件顺序很重要:先认证,再授权
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();
  1. 保护API资源
    在需要授权访问的控制器或Action上添加[Authorize]属性:
[ApiController]
[Route("api/data")]
[Authorize] // 添加该属性后,只有携带有效JWT的请求才能访问
public class DataController : ControllerBase
{
    private readonly IDatabaseService _dbService;

    public DataController(IDatabaseService dbService)
    {
        _dbService = dbService;
    }

    [HttpGet]
    public IActionResult GetSensitiveData()
    {
        var data = _dbService.GetFromDatabase();
        return Ok(data);
    }
}
三、关键注意事项
  • 核心配置必须一致:API A和API B的ValidIssuer、ValidAudience、IssuerSigningKey必须完全相同,否则API B会拒绝验证令牌。
  • 密钥安全:生产环境中不要硬编码密钥,建议使用环境变量、密钥管理工具存储,避免密钥泄露。
  • 跨域问题:如果前端从API A获取令牌后调用API B,要确保API B配置了CORS,允许前端域名的跨域请求。
  • 自定义验证:如果需要更复杂的授权逻辑(比如基于自定义Claim的验证),可以在TokenValidationParameters中添加自定义验证逻辑,或者使用策略授权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:11:36