第九章 身份验证和授权

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()
    {
        // 任何人都可以访问
    }
}

wechat_2025-07-31_105805_938


posted @ 2025-08-07 09:10  高宏顺  阅读(240)  评论(0)    收藏  举报