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

微服务JWT认证授权:是否需Identity Server/OpenIddict?

不用Identity Server/OpenIddict,仅用ASP.NET 7 Identity实现微服务JWT认证授权

完全可以不用Identity Server或OpenIddict,仅靠ASP.NET 7 Identity就能实现你的需求。下面是具体的实现步骤:

1. 在认证服务中生成JWT令牌

首先需要一个负责处理登录的服务(可以是单独的Auth API,也可以是某个业务API里的登录端点),用ASP.NET Identity验证用户名密码,并生成JWT:

核心代码示例(登录控制器)

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IConfiguration _configuration;

    public AuthController(UserManager<IdentityUser> userManager, IConfiguration configuration)
    {
        _userManager = userManager;
        _configuration = configuration;
    }

    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginModel model)
    {
        // 用Identity验证用户名密码
        var user = await _userManager.FindByNameAsync(model.Username);
        if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
        {
            // 构建用户Claims
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.NameIdentifier, user.Id)
            };
            // 添加角色Claims(如果用了角色)
            var roles = await _userManager.GetRolesAsync(user);
            claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));

            // 生成JWT令牌
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddHours(1),
                signingCredentials: creds);

            return Ok(new { Token = new JwtSecurityTokenHandler().WriteToken(token) });
        }
        return Unauthorized();
    }
}

关键配置(appsettings.json)

所有微服务的配置里要包含相同的JWT参数:

"Jwt": {
  "Key": "你的强对称密钥(所有服务共享)",
  "Issuer": "你的认证服务域名",
  "Audience": "你的微服务受众标识"
}

2. 在各个微服务中配置JWT认证

在服务A、B的Program.cs中添加JWT认证中间件,自动验证请求中的Bearer令牌:

核心代码示例

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,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
    });

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

var app = builder.Build();

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

// 其他中间件和路由配置...

这样配置后,所有带[Authorize]特性的控制器/Action会自动验证请求头中的Authorization: Bearer <token>令牌,验证通过才允许访问。

3. 基于Claims实现授权逻辑

你可以直接用角色或自定义Claims来控制访问:

示例1:基于角色授权

[Authorize(Roles = "Admin")]
[ApiController]
[Route("api/admin")]
public class AdminController : ControllerBase
{
    // 仅Admin角色可访问的接口
}

示例2:自定义Policy授权

先在Program.cs中定义Policy:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("CanEditOrder", policy =>
        policy.RequireClaim("Permission", "EditOrder"));
});

然后在Action上使用:

[Authorize(Policy = "CanEditOrder")]
[HttpPut("orders/{id}")]
public IActionResult EditOrder(int id, [FromBody] OrderModel model)
{
    // 仅持有"Permission:EditOrder" Claim的用户可访问
}

关键说明

  • 令牌验证的核心:所有微服务必须共享同一个JWT签名密钥(或非对称密钥的公钥),这样才能确认令牌是由信任的认证服务签发的,没有被篡改。
  • 为什么不用Identity Server/OpenIddict:这些框架是为复杂身份场景设计的(比如单点登录、OAuth2.0授权码流、客户端凭证流等),如果你的需求只是简单的用户名密码登录+JWT验证,ASP.NET Identity完全足够,不需要额外引入复杂框架。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:22:41