多.NET Core+React系统认证授权改造咨询:支持本地用户管理
标准解决方案:分离认证与授权+本地用户权限管理
一、核心原则先明确
- 认证(Authentication):全局统一处理,只负责确认「用户是谁」,不涉及任何系统的具体权限逻辑
- 授权(Authorization):系统本地独立管控,每个系统自行维护本系统的用户权限、访问级别、配置文件
二、JWT的合理使用结论
JWT同时承载认证和授权信息是完全合理的,但要按需划分信息范围:
- 必带认证信息:用户ID、用户名、全局唯一标识、Token过期时间、签发方等身份核心数据,放在JWT的
claims中 - 授权信息可选策略:
- 轻量场景:把跨系统通用权限(比如「超级管理员」这类全局角色)放在JWT里,减少本地系统的查询压力
- 复杂场景(适配你的需求):JWT只保留身份标识,每个系统通过本地数据库维护用户权限映射,请求时根据用户ID实时查询本地权限——这种方式更灵活,能支持本地管理员独立管控权限
三、具体架构实现步骤
1. 重构全局认证服务(原LoginAndProfileAPI)
- 彻底剥离所有授权相关逻辑,专注做纯认证:
- 处理用户登录、签发JWT(仅含身份认证
claims) - 提供JWT刷新、注销接口
- 只维护全局通用的用户基础信息(如手机号、邮箱),不碰任何系统级权限配置
- 处理用户登录、签发JWT(仅含身份认证
2. 每个系统搭建本地授权模块
每个.NET Core API系统单独实现以下功能:
- 本地权限数据库:存储本系统专属的用户权限映射表(用户ID → 系统内角色/权限/访问级别/配置文件)
- 授权校验逻辑:
- API请求管道中先验证JWT合法性(用全局认证服务的公钥或本地签名验证)
- 从JWT提取用户ID,查询本地权限数据库获取该用户在本系统的权限
- 用.NET Core的
AuthorizationPolicy做细粒度权限校验,比如[Authorize(Roles = "LocalAdmin")]
- 本地管理员功能:提供接口让本地管理员增删改查本系统的用户权限、配置文件,通过数据库隔离或业务逻辑限制,确保只能操作本系统范围内的数据
3. React前端适配方案
- 登录流程:统一跳转到全局认证服务的登录页面,获取JWT后存储在前端(推荐
sessionStorage,降低XSS风险) - 接口请求:所有系统的API请求都在请求头携带
Authorization: Bearer {JWT} - 页面渲染:从当前系统的API获取用户本地权限,动态控制组件显示/隐藏、按钮禁用等
4. 关键代码示例
.NET Core API 认证授权配置
// Program.cs 配置JWT认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "全局认证服务域名", ValidateAudience = true, ValidAudience = "本系统唯一标识", // 每个系统配置独立Audience ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("全局认证服务的密钥")) }; }); // 配置本地授权策略 builder.Services.AddAuthorization(options => { options.AddPolicy("LocalAdmin", policy => policy.RequireClaim("Permission", "ManageUsers", "ManageSystemSettings")); }); // 启用认证授权中间件 app.UseAuthentication(); app.UseAuthorization();
本地权限查询与管理示例
[Authorize] [ApiController] [Route("api/local-permissions")] public class LocalPermissionsController : ControllerBase { private readonly ILocalPermissionRepository _permissionRepo; public LocalPermissionsController(ILocalPermissionRepository permissionRepo) { _permissionRepo = permissionRepo; } [HttpGet("my")] public async Task<IActionResult> GetMyPermissions() { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var permissions = await _permissionRepo.GetPermissionsByUserId(userId); return Ok(permissions); } [Authorize(Policy = "LocalAdmin")] [HttpPost("assign")] public async Task<IActionResult> AssignPermission([FromBody] PermissionAssignment model) { // 仅允许操作本系统的用户权限 await _permissionRepo.AssignPermission(model.UserId, model.PermissionCode); return Ok(); } }
四、关键注意事项
- JWT刷新:前端要监听Token过期时间,提前调用全局认证服务的刷新接口获取新Token
- 权限实时性:本地权限变更后无需更新JWT,下次请求会自动查询最新权限
- 安全防护:JWT不存储敏感信息,前端存储注意XSS防护,API端严格验证签名和有效期
- 数据隔离:每个系统的权限数据库独立部署,避免跨系统数据泄露
内容的提问来源于stack exchange,提问作者DevAV_Souza
相关产品推荐
相关产品推荐

