在 ASP.NET Core 中,使用 JWT (JSON Web Token) 实现鉴权和授权是一种常见的方式。JWT 允许在不同系统之间安全地传输用户信息,并且信息是自包含的。下面是如何在 ASP.NET Core 中实现 JWT 鉴权和授权的步骤。
步骤 1: 安装 NuGet 包
首先,确保安装了以下 NuGet 包:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
步骤 2: 配置 JWT 身份验证
在 Startup.cs
或者 Program.cs
中配置 JWT 身份验证。
- 添加配置选项:
在 appsettings.json
文件中添加 JWT 配置,例如密钥、发行者和受众:
{
"JwtSettings": {
"Secret": "YourSecretKey", // 用于加密的密钥(应非常复杂)
"Issuer": "YourAppName", // 发行者
"Audience": "YourAppUsers", // 受众
"ExpireMinutes": 120 // 令牌有效期
}
}
- 在服务中配置 JWT 认证:
在 Program.cs
中,配置 JWT 认证方案:
var builder = WebApplication.CreateBuilder(args);
// 从配置文件中获取 JWT 设置
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
// 配置 JWT 身份验证
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Secret"])),
ClockSkew = TimeSpan.Zero // 默认的 5 分钟偏移时间
};
});
var app = builder.Build();
// 启用认证中间件
app.UseAuthentication();
app.UseAuthorization();
步骤 3: 生成 JWT Token
创建一个控制器或服务,用于生成 JWT 令牌。例如,编写一个登录 API 来生成 JWT 令牌。
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IConfiguration _configuration;
public AuthController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginRequest loginRequest)
{
// 假设你已经验证了用户名和密码
if (loginRequest.Username == "admin" && loginRequest.Password == "password")
{
var token = GenerateJwtToken(loginRequest.Username);
return Ok(new { token });
}
return Unauthorized();
}
private string GenerateJwtToken(string username)
{
var jwtSettings = _configuration.GetSection("JwtSettings");
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Secret"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: jwtSettings["Issuer"],
audience: jwtSettings["Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(double.Parse(jwtSettings["ExpireMinutes"])),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
public class LoginRequest
{
public string Username { get; set; }
public string Password { get; set; }
}
步骤 4: 保护 API 路由
使用 [Authorize]
特性来保护你的 API 路由,确保只有携带有效 JWT 令牌的请求可以访问受保护的资源。
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ProtectedController : ControllerBase
{
[HttpGet("data")]
public IActionResult GetProtectedData()
{
return Ok(new { message = "This is protected data" });
}
}
步骤 5: 客户端请求
客户端在请求受保护的 API 时,必须在请求头中添加 Authorization
字段,格式为 Bearer <token>
:
GET /api/protected/data HTTP/1.1
Host: yourdomain.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
可选:角色授权
如果你需要基于角色进行授权,可以在生成 JWT 令牌时添加角色信息:
private string GenerateJwtToken(string username)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, username),
new Claim(ClaimTypes.Role, "Admin"), // 添加角色
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
// 剩余代码与前面一致
}
然后使用 [Authorize(Roles = "Admin")]
特性来限定只有特定角色的用户才能访问:
[Authorize(Roles = "Admin")]
[HttpGet("admin-data")]
public IActionResult GetAdminData()
{
return Ok(new { message = "This is admin data" });
}