上一篇 : 《nacos源码之Auth(权限)模块-1(授权过滤器与控制器缓存)》
上篇介绍了Nacos权限模块的实现逻辑,其中权限校验的实现实现权限管理
模块实现的,这篇文章就继续介绍权限管理的实现与权限配置。
AuthManager
权限管理接口定义在auth模块中,AuthManager
接口中仅定义了两个方法login()
和auth()
:
public interface AuthManager {
/** 登录接口通过请求获取到当前用户 */
User login(Object request) throws AccessException;
/** 授权校验接口 */
void auth(Permission permission, User user) throws AccessException;
}
login()
接口,用户用过请求获取当前用户。auth()
接口,进行权限校验。权限管理实现在NacosAuthManager
类实现,该类在console
模块中。Nacos权限管理使用了Sping的安全框架spring security
。
内部有三个重要对象:
/** JWT令牌管理 */
@Autowired
private JwtTokenManager tokenManager;
/** spring security中的权限管理 */
@Autowired
private AuthenticationManager authenticationManager;
/** 角色服务 */
@Autowired
private NacosRoleServiceImpl roleService;
tokenManager
令牌管理,nacos使用JWT作为令牌。令牌管理中实现了令牌创建
,令牌解析
,令牌校验
功能。令牌管理集成了AuthConfigs
权限配置用来创建令牌,例如:有效期authenticationManager
该对象是spring security中的权限管理类。roleService
角色管理。内部主要是访问数据库完成用户角色与权限配置的匹配。角色管理主要涉及到了用户表(users),角色表(roles),权限表(permissions)。内部实现逻辑还是比较简单的。
为什么单独说一下数据库实现,因为Nacos在权限操作时封装了两套数据库实现。
拿 RolePersistService
(config模块中)定义了获取角色
,新增角色
,删除角色
等接口,Nacos为该接口做了两套实现分别是EmbeddedRolePersistServiceImpl
和 ExternalRolePersistServiceImpl
:
EmbeddedRolePersistServiceImpl
嵌入式存储实现,也是核心实现方式,其原理就是内部定义了一个DatabaseOperate
数据操作者,Naco为该接口做了两个实现分别是分布式实现
,和单例实现
,关系如下图 。ExternalRolePersistServiceImpl
该接口功能与逻辑与EmbeddedRolePersistServiceImpl
没有差别,这个也符合单一职能原则,只是内部直接使用了Spirng JdbcTemplate 进行实现。具体使用哪个实现控制在注解
@Conditional(value = ConditionOnExternalStorage.class)
最终控制由nacos的
nacos.standalone
配置项决定
StandaloneDatabaseOperateImpl
单例实现其实还是JdbcTemplate,然后使用了Spring 的 TransactionTemplate
,单例模式并不是重点。生产环境亦不建议使用单例模式。DistributedDatabaseOperateImpl
分布式实现,分布式实现需要保证数据一致性因此使用CP模式实现,Nacos的CP模式使用了 Raft
算法。需要了解CAP原则,CP模型,AP模型的话可以参考 《一文道尽分布式的CAP原则》
JRaft实现流程如下:
JRaft 内容过长,后面会出一篇讲解 Raft 协议的文章,尽情期待。
直接上代码:
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock()
有几篇关于锁的文章可供大家参考:
auth模块的权限配置类在auth模块的common包中,定义如下(源码太长,我们这里仅摘抄一部分,并且添加注释):
package com.alibaba.nacos.auth.common;
@Configuration
public class AuthConfigs {
@JustForTest
private static Boolean cachingEnabled = null;
// 安全证书
@Value("${nacos.core.auth.default.token.secret.key:}")
private String secretKey;
// 安全证书,只是格式不同
private byte[] secretKeyBytes;
// 授权token的有效时间默认是18000秒也就是5个小时
@Value("${nacos.core.auth.default.token.expire.seconds:18000}")
private long tokenValidityInSeconds;
// 授权系统类型
@Value("${nacos.core.auth.system.type:}")
private String nacosAuthSystemType;
@Value("${nacos.core.auth.server.identity.key:}")
private String serverIdentityKey;
@Value(("${nacos.core.auth.server.identity.value:}"))
private String serverIdentityValue;
// 白名单
@Value(("${nacos.core.auth.enable.userAgentAuthWhite:true}"))
private boolean enableUserAgentAuthWhite;
}
配置对象多长具体代码请见 : https://github.com/keepgoon/nacos/blob/develop/auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java
巧妙使用工具,将协议与工具结合,例如CP协议与JDK锁结合。
做了分布式与单点的数据操作适配,充分利用了Spring 的注解。
上一篇 : 《nacos源码之Auth(权限)模块-1(授权过滤器与控制器缓存)》