认证系统(Authentication)与权限系统(Authorization)解耦设计
您是否曾经与其他开发人员讨论过应用程序的权限系统,并很快意识到您也在谈论它的认证系统? 这是相当不幸的,但这两个完全不同的系统经常被合并在一起。
认证服务像护照(证明你是谁),权限服务像签证(允许你在哪里做什么)
- 护照颁发后不会每天更新(登录令牌有效期)
- 签证可动态调整(权限实时刷新)
通过严格分离关注点,系统同时获得 安全性和可维护性 的提升。
在系统设计中一个常见的认知误区——权限系统(Authorization)和认证系统(Authentication)本质上是两个独立的安全边界,但常因架构耦合被混为一谈。
| 维度 | 认证系统(Authentication) | 权限系统(Authorization) |
关键问题 |
“你是谁?”(身份验证) | “你能做什么?”(资源许可) |
| 技术目标 | 证明用户身份真实性 | 控制资源访问边界 |
| 核心组件 | 密码/OAuth/生物识别 | RBAC/ReBAC/ABAC策略引擎 |
| 输出结果 | 用户标识符(如:user_id) |
权限决策(Allow/Deny) |
| 失效场景 | 凭证泄露 → 冒充风险 | 策略错误 → 越权操作 |
一、解耦实践方案
1.1. 架构分层设计
- 认证服务:仅负责生成身份令牌(如JWT中的
sub字段) - 权限服务:独立微服务,接收
user_id+动作+资源,返回布尔值
1.2. 协议级分离(OAuth 2.0为例)
- 认证阶段:获取
access_token(证明你是合法用户) - 权限阶段:业务服务用
access_token向权限服务发起鉴权请求
// AuthorizationService.cs - 策略驱动的权限检查
public class AuthorizationService
{
private readonly IRolePermissionRepository _repo; // 注入权限数据源
public bool CheckPermission(int userId, string resource, string action)
{
// 示例:基于角色的权限校验(RBAC)
var roles = _repo.GetUserRoles(userId);
return _repo.GetPermissions(roles)
.Exists(p => p.Resource == resource && p.Action == action);
}
}
// ABAC(属性基访问控制)扩展
public class AttributeAuthorizationService
{
public bool CheckAttributes(int userId, Resource resource, Action action)
{
var userAttributes = _repo.GetUserAttributes(userId);
var policy = _repo.GetPolicyForResource(resource);
// 执行属性匹配(如:用户部门=资源所属部门)
return policy.Evaluate(userAttributes);
}
}
二、最佳实践参考
标准协议采用
- 认证:OpenID Connect(OIDC)
- 权限:OAuth 2.0 Scope(静态粗粒度) + https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/(动态细粒度)
基础设施选择
- 认证组件:Keycloak/Auth0/Okta
- 权限引擎:Casbin/OPA(Open Policy Agent)/SpiceDB
调试工具链
- 权限测试框架:
OPA Rego Playground/ SpiceDB Playground - 登录流诊断:
oidc-client-js调试器
- 权限测试框架:
欢迎大家扫描下面二维码成为我的客户,扶你上云


浙公网安备 33010602011771号