如果是网关等服务,可以将路由及每个路由的权限缓存到redis数据库中,用户访问,在网关进行鉴权:
- token比对redis缓存的token,不存在返回
- token进行jwt解析,获取roles
- 通过api的path和访问模式在redis数据库中获取该接口通行的roles
- token中的roles和api对应的roles有相交说明有权限,否则返回
- roles同时通过
ReactiveSecurityContextHolder
进行设置
1. 启动时api信息写入redis
- 通过
PostConstruct
在启动时将数据库中的数据转存到redis中 - key通过
api_path_method
的方式存储:String key = "api_" + api.getUrl().trim() + "_" + api.getRemark();
/**
* @author: ffzs
* @Date: 2020/9/1 下午12:52
*/
@Component
@AllArgsConstructor
@Slf4j
@Order(1)
public class prepareRedisData {
private final ReactiveRedisTemplate<String, String> redisTemplate;
private final SysApiService sysApiService;
@PostConstruct
public void route2Redis() {
sysApiService.findAll()
.flatMap(api -> {
String key = "api_" + api.getUrl().trim() + "_" + api.getRemark();
redisTemplate.delete(key);
if (!api.getRoles().isEmpty())
return redisTemplate.opsForSet()
.add(key, api.getRoles().toArray(new String[0]));
else return Mono.empty();
})
.subscribe();
log.info("routes import to redis completed");
}
}
2.修改WebFilter进行鉴权
- 检查token是否存在
- 检查token是否符合要求
- 获取redis中的roles进行比对如果用户roles在redis中的数量大于等于1符合要求
- 根据token获得
Authentication
Authentication
写入ReactiveSecurityContextHolder