第九章 身份验证和授权
9.1 身份验证基础
身份验证与授权的区别
- 身份验证(Authentication):验证用户是谁
- 授权(Authorization):确定用户可以做什么
JWT Bearer 认证
JWT (JSON Web Token) 是一种无状态的身份验证方法,适用于API。
配置JWT认证
// 安装包
// dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
// 配置服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
builder.Configuration["JWT:Secret"])),
ValidateIssuer = true,
ValidIssuer = builder.Configuration["JWT:Issuer"],
ValidateAudience = true,
ValidAudience = builder.Configuration["JWT:Audience"],
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
// 添加授权
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
options.AddPolicy("UserOnly", policy => policy.RequireRole("User"));
});
// 启用中间件
app.UseAuthentication();
app.UseAuthorization();
9.2 实现用户注册和登录
用户模型
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public string Role { get; set; } = "User";
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
public class LoginRequest
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}
public class RegisterRequest
{
[Required]
public string Username { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[MinLength(6)]
public string Password { get; set; }
}
认证控制器
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IUserService _userService;
private readonly ITokenService _tokenService;
public AuthController(IUserService userService, ITokenService tokenService)
{
_userService = userService;
_tokenService = tokenService;
}
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterRequest request)
{
if (await _userService.ExistsAsync(request.Username))
{
return BadRequest("用户名已存在");
}
var user = await _userService.CreateAsync(request);
var token = _tokenService.GenerateToken(user);
return Ok(new { Token = token, User = new { user.Id, user.Username, user.Email } });
}
[HttpPost("login")]
public async Task<IActionResult> Login(LoginRequest request)
{
var user = await _userService.ValidateAsync(request.Username, request.Password);
if (user == null)
{
return Unauthorized("用户名或密码错误");
}
var token = _tokenService.GenerateToken(user);
return Ok(new { Token = token, User = new { user.Id, user.Username, user.Email } });
}
}
9.3 保护API端点
使用授权特性
[ApiController]
[Route("api/[controller]")]
[Authorize] // 所有方法都需要认证
public class TodoItemsController : ControllerBase
{
[HttpGet]
public async Task<IActionResult> GetTodos()
{
// 需要认证的用户才能访问
}
[HttpPost]
[Authorize(Roles = "Admin")] // 仅管理员可以创建
public async Task<IActionResult> CreateTodo(TodoItem item)
{
// 仅管理员可以访问
}
[HttpGet("public")]
[AllowAnonymous] // 允许匿名访问
public async Task<IActionResult> GetPublicTodos()
{
// 任何人都可以访问
}
}


浙公网安备 33010602011771号