接口鉴权
当你要给接口加权限点、排查“有菜单但点不了按钮”、或确认后端鉴权与前端路由/按钮如何协作时,优先看这篇。
youlai-aspnet 采用经典的 RBAC(Role-Based Access Control) 权限模型,本文涵盖:
- 用户/角色/菜单/权限标识的关系与建模
- 后端接口鉴权的实现方式与常见问题排查
- 与前端按钮权限的联动约定
RBAC 模型
核心概念:
| 概念 | 说明 |
|---|---|
| 用户(User) | 系统操作者,通过角色间接获得权限 |
| 角色(Role) | 权限的集合,用户与权限的桥梁 |
| 菜单(Menu) | 系统功能入口,关联权限标识 |
| 权限标识(Perm) | 功能权限的唯一标识,如 sys:user:create |
权限层级:
数据库设计
核心表结构:
权限实现
基于策略的授权
ASP.NET Core 使用 Policy-based 授权:
csharp
// HasPermAttribute.cs
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class HasPermAttribute : AuthorizeAttribute
{
public HasPermAttribute(string perm)
{
Policy = SecurityConstants.PermissionPolicyPrefix + perm;
}
}控制器使用
csharp
// UsersController.cs
[ApiController]
[Route("api/v1/users")]
public class UsersController : ControllerBase
{
[HttpGet]
[HasPerm("sys:user:view")] // 权限点
public async Task<IActionResult> GetPage([FromQuery] UserQuery query)
{
// ...
}
[HttpPost]
[HasPerm("sys:user:create")]
public async Task<IActionResult> Create([FromBody] UserForm form)
{
// ...
}
}权限策略提供器
csharp
// PermissionPolicyProvider.cs
public sealed class PermissionPolicyProvider : DefaultAuthorizationPolicyProvider
{
public override async Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
{
if (policyName.StartsWith(SecurityConstants.PermissionPolicyPrefix))
{
var perm = policyName[SecurityConstants.PermissionPolicyPrefix.Length..];
return new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim(SecurityConstants.PermClaimType, perm)
.Build();
}
return await base.GetPolicyAsync(policyName);
}
}权限校验流程
权限常量
csharp
// SecurityConstants.cs
public static class SecurityConstants
{
public const string PermissionPolicyPrefix = "Perm:";
public const string PermClaimType = "perm";
public const string RootRoleCode = "ROOT";
}前后端协同
权限标识约定
格式:{模块}:{资源}:{操作}
| 模块 | 资源 | 操作 | 示例 |
|---|---|---|---|
sys | user | view | sys:user:view |
sys | user | create | sys:user:create |
sys | user | update | sys:user:update |
sys | user | delete | sys:user:delete |
前端按钮权限
vue
<template>
<el-button v-perm="'sys:user:create'">新增</el-button>
<el-button v-perm="'sys:user:update'">编辑</el-button>
<el-button v-perm="'sys:user:delete'">删除</el-button>
</template>常见问题
权限不生效
现象:添加了权限但仍然 403
排查步骤:
- 检查权限是否正确关联到角色
- 检查用户是否拥有该角色
- 检查 Token 是否包含权限声明
- 清除 Redis 权限缓存
按钮不显示
现象:有权限但按钮不显示
排查步骤:
- 检查前端权限指令
- 确认权限标识与后端一致
- 检查菜单是否关联权限
相关文件
| 文件 | 说明 |
|---|---|
Youlai.Api/Security/HasPermAttribute.cs | 权限特性 |
Youlai.Api/Security/PermissionPolicyProvider.cs | 策略提供器 |
Youlai.Application/Security/SecurityConstants.cs | 安全常量 |
Youlai.Application/Security/IDataPermissionService.cs | 权限服务 |
