Skip to content

接口鉴权

当你要给接口加权限点、排查“有菜单但点不了按钮”、或确认后端鉴权与前端路由/按钮如何协作时,优先看这篇。

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";
}

前后端协同

权限标识约定

格式:{模块}:{资源}:{操作}

模块资源操作示例
sysuserviewsys:user:view
sysusercreatesys:user:create
sysuserupdatesys:user:update
sysuserdeletesys: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

排查步骤

  1. 检查权限是否正确关联到角色
  2. 检查用户是否拥有该角色
  3. 检查 Token 是否包含权限声明
  4. 清除 Redis 权限缓存

按钮不显示

现象:有权限但按钮不显示

排查步骤

  1. 检查前端权限指令
  2. 确认权限标识与后端一致
  3. 检查菜单是否关联权限

相关文件

文件说明
Youlai.Api/Security/HasPermAttribute.cs权限特性
Youlai.Api/Security/PermissionPolicyProvider.cs策略提供器
Youlai.Application/Security/SecurityConstants.cs安全常量
Youlai.Application/Security/IDataPermissionService.cs权限服务

基于 MIT 许可发布 · 由 ❤️ 和 ☕ 驱动 · 支持作者