Files
Academic-Affairs-System/src/Jiaowu.Api/Controllers/AuthController.cs
T
biss bcc4d33bd5 多角色账号按 All > College > Class > Self 自动取最高权限。
学院管理员限制在所属学院。
辅导员通过稳定账号 ID 绑定行政班,避免重名串班。
教师只能访问本人档案、授课课程和所授课学生。
学生只能访问本人档案及所在班级课程。
教师/学生角色会自动校验并绑定工号或学号档案。
超级管理员可在用户页面调整角色、学院、工号/学号,并预览生效后的数据范围。
2026-07-24 14:54:30 +08:00

95 lines
3.0 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace Jiaowu.Api.Controllers;
[ApiController]
[Route("api/auth")]
public sealed class AuthController(
UserManager<ApplicationUser> userManager,
ITokenService tokenService) : ControllerBase
{
[AllowAnonymous]
[HttpPost("login")]
public async Task<ActionResult<LoginResponse>> Login(LoginRequest request)
{
var user = await userManager.FindByNameAsync(request.UserName);
if (user is null || !user.IsEnabled)
{
return Unauthorized(new ProblemDetails
{
Title = "登录失败",
Detail = "账号或密码不正确,或账号已停用。",
Status = StatusCodes.Status401Unauthorized
});
}
if (await userManager.IsLockedOutAsync(user) ||
!await userManager.CheckPasswordAsync(user, request.Password))
{
await userManager.AccessFailedAsync(user);
return Unauthorized(new ProblemDetails
{
Title = "登录失败",
Detail = "账号或密码不正确,或账号已停用。",
Status = StatusCodes.Status401Unauthorized
});
}
await userManager.ResetAccessFailedCountAsync(user);
user.LastLoginAt = DateTime.UtcNow;
await userManager.UpdateAsync(user);
var roles = await userManager.GetRolesAsync(user);
return new LoginResponse(
tokenService.Create(user, roles),
new CurrentUserResponse(
user.Id,
user.UserName!,
user.DisplayName,
roles,
user.CollegeId,
EffectiveDataScopeResolver.Resolve(roles).ToString()));
}
[Authorize]
[HttpGet("me")]
public async Task<ActionResult<CurrentUserResponse>> Me()
{
var id = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = id is null ? null : await userManager.FindByIdAsync(id);
if (user is null || !user.IsEnabled)
{
return Unauthorized();
}
var roles = await userManager.GetRolesAsync(user);
return new CurrentUserResponse(
user.Id,
user.UserName!,
user.DisplayName,
roles,
user.CollegeId,
EffectiveDataScopeResolver.Resolve(roles).ToString());
}
}
public sealed record LoginRequest(
[Required, MaxLength(100)] string UserName,
[Required, MaxLength(100)] string Password);
public sealed record LoginResponse(string Token, CurrentUserResponse User);
public sealed record CurrentUserResponse(
Guid Id,
string UserName,
string DisplayName,
IEnumerable<string> Roles,
Guid? CollegeId,
string EffectiveDataScope);