#动态权限

2025-12-21 06:25:31

# 动态权限 动态授权指的是:当系统资源、或者用户角色发生变动的时候,用户权限动态更新,即刻生效。

也就说在以下场景下,需要动态刷新系统权限逻辑:

系统资源变更。如:新增系统资源、修改了资源的 url 或者权限标识、删除了系统资源等; 角色权限变更。如:对角色进行了授权操作、修改了角色拥有的权限等。 用户角色变更。如:修改用户所属角色。 对应以上场景,Heimdall框架的实现逻辑:

系统资源变更:清除所有缓存系统资源,然后重新载入; 角色权限变更:角色权限变化,角色下属所有用户的权限会一起变化,这种场景下,可以先通过角色获取到下属所有用户,然后逐个清理用户权限,也可以直接全部清理所有缓存的用户权限。推荐:全部清理用户权限。 用户角色变更:这种情况与角色权限变更处理逻辑相同。 # 系统资源变更 首先需要注入权限缓存 DAO

@Autowired

private AuthorizationMetaDataCacheDao authorizationMetaDataCacheDao;

然后,在资源的新增、修改、删除操作完成后,清理系统权限缓存,如下所示:

//新增资源

public SysResourceDTO save(SysResourceVO param) {

final SysResourceEntity toSave = sysResourceMapper.voToEntity(param);

final SysResourceEntity saved = sysResourceRepository.saveAndFlush(toSave);

//新增加了系统权限,将缓存的系统权限清空,便于下次访问重新加载生效

authorizationMetaDataCacheDao.clearSysAuthorities();

return sysResourceMapper.toDto(saved);

}

//修改资源信息

public SysResourceDTO update(SysResourceVO param) {

final Optional toUpdate = sysResourceRepository.findById(param.getId());

if (toUpdate.isPresent()) {

final SysResourceEntity toUpdated = toUpdate.get();

toUpdated.setName(param.getName());

toUpdated.setUrl(param.getUrl());

toUpdated.setMethod(param.getMethod());

final SysResourceEntity updated = sysResourceRepository.saveAndFlush(toUpdated);

//修改了系统权限,将缓存的系统权限清空,便于下次访问重新加载生效

//严谨一些,此处应该判断一下修改的信息是否对拦截规则有影响

//没有影响则可以不用清理缓存

authorizationMetaDataCacheDao.clearSysAuthorities();

return sysResourceMapper.toDto(updated);

} else {

throw new IllegalArgumentException("参数错误");

}

}

//删除资源

public void deleteById(String id) {

final Optional toDelete = sysResourceRepository.findById(id);

if (toDelete.isPresent()) {

sysResourceRepository.delete(toDelete.get());

//删除了系统权限,将缓存的系统权限清空,便于下次访问重新加载生效

authorizationMetaDataCacheDao.clearSysAuthorities();

} else {

throw new IllegalArgumentException("参数错误");

}

}

# 角色权限变更 当对角色权限发生变动,也就是修改角色信息和删除角色信息的时候,动态清理用户权限。

//修改角色信息

public SysRoleDTO update(SysRoleVO param) {

final Optional toUpdate = sysRoleRepository.findById(param.getId());

if (toUpdate.isPresent()) {

final SysRoleEntity toUpdated = toUpdate.get();

toUpdated.setName(param.getName());

toUpdated.setDescription(param.getDescription());

//修改角色的权限资源

if(null!=param.getResources()&&!param.getResources().isEmpty()){

toUpdated.setResources(sysResourceMapper.voListToEntityList(param.getResources()));

}

final SysRoleEntity updated = sysRoleRepository.saveAndFlush(toUpdated);

//角色权限资源发生变动,清理所有用户权限缓存

//这里严谨一些,应该判断一下,是不是有资源发生变动,如果角色资源没变动,则不需要清理

sessionDAO.clearAllUserAuthorities();

return sysRoleMapper.toDto(updated);

} else {

throw new IllegalArgumentException("参数错误");

}

}

//删除角色,则此角色下所有用户的权限也会相应变动

public void deleteById(String id) {

final Optional toDelete = sysRoleRepository.findById(id);

if (toDelete.isPresent()) {

sysRoleRepository.delete(toDelete.get());

//角色删除后,清理所有用户的权限缓存

sessionDAO.clearAllUserAuthorities();

} else {

throw new IllegalArgumentException("参数错误");

}

}

详细实现细节,请参考源码