构建一个包含 JWT(JSON Web Token)鉴权的 Web API 是一种常见的做法,用于保护 API 端点并验证用户身份。以下是一个基于 ASP.NET Core 的完整示例,展示如何实现 JWT 鉴权。
1. 创建 ASP.NET Core Web API 项目
使用 .NET CLI 或 Visual Studio 创建一个新的 Web API 项目:
bash
dotnet new webapi -n JwtAuthApi
cd JwtAuthApi
2. 安装必要的 NuGet 包
确保安装了以下包(通常默认已包含):
Microsoft.AspNetCore.Authentication.JwtBearer
Microsoft.IdentityModel.Tokens
System.IdentityModel.Tokens.Jwt
如果未安装,可以运行以下命令:
bash
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
3. 配置 JWT 鉴权
(1) 修改 appsettings.json
在 appsettings.json
中添加 JWT 配置:
json
{
"Jwt": {
"Key": "YourSecretKeyForJwtAuthentication", // 用于签名的密钥
"Issuer": "YourIssuer", // 发行者
"Audience": "YourAudience" // 受众
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
(2) 配置服务 (Program.cs
)
在 Program.cs
中配置 JWT 鉴权服务:
csharp
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 添加 JWT 鉴权
var jwtSettings = builder.Configuration.GetSection("Jwt");
var key = Encoding.ASCII.GetBytes(jwtSettings["Key"]);
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(key)
};
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// 使用鉴权中间件
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
4. 创建用户登录和生成 JWT 的逻辑
(1) 创建模型类
创建一个简单的用户模型和返回的响应模型:
csharp
public class UserModel
{
public string Username { get; set; }
public string Password { get; set; }
}
public class AuthResponse
{
public string Token { get; set; }
public DateTime Expiration { get; set; }
}
(2) 创建生成 JWT 的方法
在 Controllers/AuthController.cs
中实现登录和生成 JWT 的逻辑:
csharp
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] UserModel user)
{
// 模拟用户验证(实际应从数据库中验证)
if (user.Username == "admin" && user.Password == "password")
{
var token = GenerateJwtToken(user.Username);
return Ok(new AuthResponse
{
Token = token,
Expiration = DateTime.UtcNow.AddMinutes(30) // 设置过期时间
});
}
return Unauthorized(new { message = "Invalid username or password" });
}
private string GenerateJwtToken(string username)
{
var jwtSettings = _configuration.GetSection("Jwt");
var key = Encoding.ASCII.GetBytes(jwtSettings["Key"]);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, "Admin") // 示例角色
}),
Expires = DateTime.UtcNow.AddMinutes(30), // 设置过期时间
Issuer = jwtSettings["Issuer"],
Audience = jwtSettings["Audience"],
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(securityToken);
}
}
5. 创建受保护的 API 端点
(1) 创建一个受保护的控制器
在 Controllers/SecureController.cs
中创建一个需要 JWT 鉴权的端点:
csharp
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
[Authorize] // 要求鉴权
public class SecureController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var username = User.Identity.Name;
return Ok(new { message = $"Hello, {username}! This is a secure endpoint." });
}
}
6. 测试 API
(1) 登录获取 JWT
发送 POST 请求到 /api/auth/login
,请求体如下:
json
{
"username": "admin",
"password": "password"
}
响应会返回一个 JWT Token。
(2) 访问受保护的端点
将获取到的 Token 添加到请求头中,格式为:
Authorization: Bearer <JWT_TOKEN>
然后访问 /api/secure
,你将看到受保护的响应。
总结
通过以上步骤,我们实现了一个包含 JWT 鉴权的 Web API。这个示例展示了如何生成 JWT、验证 JWT,以及如何保护 API 端点。你可以根据实际需求扩展功能,例如从数据库验证用户、支持角色权限等。