using Sharp.NetServer.Attributes; using Sharp.NetServer.Controllers; using Sharp.NetServer.Models; using Sharp.NetServer.Abstractions; using System.Security.Claims; namespace NetServer.Test.Examples.Controllers; /// /// 认证控制器示例 /// [ApiController] [Route("api/auth")] public class AuthController : BaseController { // 模拟用户数据库 private static readonly Dictionary UserCredentials = new() { { "admin", "admin123" }, { "user", "user123" } }; /// /// 用户登录 /// POST /api/auth/login /// Body: { "username": "admin", "password": "admin123" } /// [AllowAnonymous] [RateLimit(10, RateLimitScope.Ip)] // 防止暴力破解 [HttpPost("login")] public async Task LoginAsync(HttpContext context) { var loginData = await ReadJsonBodyAsync>(context); if (loginData == null || !loginData.TryGetValue("username", out var username) || !loginData.TryGetValue("password", out var password)) { await BadRequestAsync(context, "用户名和密码不能为空"); return; } // 验证凭据 if (UserCredentials.TryGetValue(username, out var correctPassword) && correctPassword == password) { // 生成简单的 Token(实际应用中应使用 JWT) var token = GenerateSimpleToken(username); // 设置 Cookie SetCookie(context, "auth_token", token, 3600); await WriteSuccessResponseAsync(context, new { token, username, role = username == "admin" ? "Admin" : "User", expiresIn = 3600 }, "登录成功"); } else { await UnauthorizedAsync(context, "用户名或密码错误"); } } /// /// 用户登出 /// POST /api/auth/logout /// [Authorize] [HttpPost("logout")] public async Task LogoutAsync(HttpContext context) { // 删除 Cookie DeleteCookie(context, "auth_token"); await WriteSuccessResponseAsync(context, new { }, "登出成功"); } /// /// 获取当前用户信息 /// GET /api/auth/me /// [Authorize] [HttpGet("me")] public async Task GetCurrentUserAsync(HttpContext context) { var username = context.User?.Identity?.Name ?? "Unknown"; var roles = context.User?.Claims .Where(c => c.Type == ClaimTypes.Role) .Select(c => c.Value) .ToList() ?? new List(); await WriteSuccessResponseAsync(context, new { username, roles, isAuthenticated = context.User?.Identity?.IsAuthenticated ?? false }); } /// /// 修改密码 /// POST /api/auth/change-password /// Body: { "oldPassword": "admin123", "newPassword": "newpass123" } /// [Authorize] [RateLimit(5, RateLimitScope.User)] [HttpPost("change-password")] public async Task ChangePasswordAsync(HttpContext context) { var username = context.User?.Identity?.Name; if (string.IsNullOrEmpty(username)) { await UnauthorizedAsync(context); return; } var passwordData = await ReadJsonBodyAsync>(context); if (passwordData == null || !passwordData.TryGetValue("oldPassword", out var oldPassword) || !passwordData.TryGetValue("newPassword", out var newPassword)) { await BadRequestAsync(context, "旧密码和新密码不能为空"); return; } // 验证旧密码 if (!UserCredentials.TryGetValue(username, out var currentPassword) || currentPassword != oldPassword) { await BadRequestAsync(context, "旧密码错误"); return; } // 更新密码 UserCredentials[username] = newPassword; await WriteSuccessResponseAsync(context, new { }, "密码修改成功"); } /// /// 刷新 Token /// POST /api/auth/refresh /// [Authorize] [HttpPost("refresh")] public async Task RefreshTokenAsync(HttpContext context) { var username = context.User?.Identity?.Name; if (string.IsNullOrEmpty(username)) { await UnauthorizedAsync(context); return; } var newToken = GenerateSimpleToken(username); SetCookie(context, "auth_token", newToken, 3600); await WriteSuccessResponseAsync(context, new { token = newToken, expiresIn = 3600 }, "Token 刷新成功"); } private static string GenerateSimpleToken(string username) { // 简单的 Token 生成(实际应用中应使用 JWT) var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var role = username == "admin" ? "Admin" : "User"; return Convert.ToBase64String( System.Text.Encoding.UTF8.GetBytes($"{username}:{role}:{timestamp}") ); } } /// /// 简单的认证提供者实现 /// public class SimpleAuthenticationProvider : IAuthenticationProvider { public Task AuthenticateAsync(string? token) { if (string.IsNullOrEmpty(token)) return Task.FromResult(null); try { // 解析简单的 Token var decoded = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(token)); var parts = decoded.Split(':'); if (parts.Length >= 2) { var username = parts[0]; var role = parts[1]; var claims = new List { new(ClaimTypes.Name, username), new(ClaimTypes.Role, role) }; var identity = new ClaimsIdentity(claims, "SimpleAuth"); var principal = new ClaimsPrincipal(identity); return Task.FromResult(principal); } } catch { // Token 解析失败 } return Task.FromResult(null); } }