1. 简介
JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络应用环境间以紧凑、URL 安全的方式传递声明(Claim)。JWT 常用于前后端分离的 Web 应用中,特别是微服务架构和单页应用(SPA)中。本教程将介绍如何在 C# .NET Core Web API 中配置 JWT 认证,帮助开发者实现安全、可扩展的身份验证机制。
2. JWT 结构
JWT 由三部分组成:
- Header(头部):声明类型(JWT)和所使用的签名算法(如 HS256、RS256)。
- Payload(载荷):包含声明,通常是用户信息或自定义数据。
- Signature(签名):通过 Header 和 Payload 加密生成的签名,用于验证 JWT 的真实性和完整性。
3. 准备工作
3.1 创建 .NET Core Web API 项目
使用以下命令创建一个新的 .NET Core Web API 项目:
bash
dotnet new webapi -n JwtAuthDemo
cd JwtAuthDemo
3.2 安装必要的 NuGet 包
安装以下 NuGet 包以支持 JWT 认证:
bash
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt
4. 配置 JWT 参数
在 appsettings.json 文件中配置 JWT 相关的参数:
javascript
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Jwt": {
"SecretKey": "your-very-secure-key-at-least-32-characters-long", // 密钥,至少 32 位
"Issuer": "your-issuer", // 签发者
"Audience": "your-audience", // 受众
"ExpirationMinutes": 60 // 过期时间(分钟)
}
}
5. 配置 JWT 认证服务
在 Program.cs 文件中配置 JWT 认证服务:
cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 添加控制器服务
builder.Services.AddControllers();
// 配置 JWT 认证
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true, // 验证签发者
ValidIssuer = builder.Configuration["Jwt:Issuer"], // 签发者
ValidateAudience = true, // 验证受众
ValidAudience = builder.Configuration["Jwt:Audience"], // 受众
ValidateLifetime = true, // 验证过期时间
ValidateIssuerSigningKey = true, // 验证签名密钥
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"])), // 签名密钥
ClockSkew = TimeSpan.Zero // 关闭时间偏差容忍
};
});
// 添加授权服务
builder.Services.AddAuthorization();
var app = builder.Build();
// 启用认证和授权中间件
app.UseAuthentication();
app.UseAuthorization();
// 配置 HTTP 请求管道
app.MapControllers();
app.Run();
6. 创建 JWT 工具类
创建一个工具类 JwtTokenHelper.cs,用于生成 JWT 令牌:
cs
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
public class JwtTokenHelper
{
private readonly IConfiguration _configuration;
public JwtTokenHelper(IConfiguration configuration)
{
_configuration = configuration;
}
public string GenerateToken(string username, string role = null)
{
// 从配置文件中读取 JWT 参数
var secretKey = Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]);
var issuer = _configuration["Jwt:Issuer"];
var audience = _configuration["Jwt:Audience"];
var expirationMinutes = int.Parse(_configuration["Jwt:ExpirationMinutes"]);
// 定义声明(Claims)
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), // 唯一标识
new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()) // 签发时间
};
// 添加角色声明(如果存在)
if (!string.IsNullOrEmpty(role))
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
// 生成签名密钥
var key = new SymmetricSecurityKey(secretKey);
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// 创建 JWT 令牌
var token = new JwtSecurityToken(
issuer: issuer,
audience: audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(expirationMinutes),
signingCredentials: creds);
// 返回 JWT 字符串
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
7. 创建登录接口
创建一个 AuthController 用于处理用户登录并生成 JWT 令牌:
cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IConfiguration _configuration;
public AuthController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel model)
{
// 这里应验证用户名和密码(示例中简化处理)
if (model.Username == "admin" && model.Password == "password")
{
var tokenHelper = new JwtTokenHelper(_configuration);
var token = tokenHelper.GenerateToken(model.Username, "Admin");
return Ok(new
{
Token = token
});
}
return Unauthorized();
}
}
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
8. 保护 API 接口
使用 [Authorize] 特性标记需要认证的控制器或方法:
cs
[ApiController]
[Route("api/[controller]")]
[Authorize] // 整个控制器需要认证
public class SecureController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var username = User.Identity.Name;
return Ok(new
{
Message = $"Hello, {username}",
Time = DateTime.Now
});
}
[HttpGet("admin")]
[Authorize(Roles = "Admin")] // 仅 Admin 角色可访问
public IActionResult AdminOnly()
{
return Ok(new
{
Message = "This is admin-only content."
});
}
}
9. 测试 JWT 认证
9.1 获取 Token
使用 Postman 或其他工具发送 POST 请求到 /api/auth/login,请求体为:
cs
{
"username": "admin",
"password": "password"
}
成功响应:
cs
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
9.2 访问受保护的接口
在请求头中添加 Authorization 字段,值为 Bearer <token>,例如:
cs
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
发送 GET 请求到 /api/secure,成功响应:
cs
{
"message": "Hello, admin",
"time": "2025-05-20T12:00:00Z"
}
10. 总结
本教程详细介绍了如何在 C# .NET Core Web API 中配置 JWT 认证,包括:
- 创建项目并安装必要的 NuGet 包。
- 配置 JWT 参数。
- 实现 JWT 认证服务。
- 创建 JWT 工具类用于生成令牌。
- 创建登录接口并返回 JWT 令牌。
- 使用
[Authorize]特性保护 API 接口。 - 测试 JWT 认证流程。
通过本教程,开发者可以快速实现基于 JWT 的身份验证机制,提升 Web API 的安全性。