8-OAuth2.0实战:木谷博客系统RBAC权限设计

8-OAuth2.0实战:木谷博客系统RBAC权限设计这节内容说一下木谷博客系统的权限设计 采用现在主流的权限模型 RBAC 对应关系如下 以上 5 张表都在 mugu auth server 这个库中 该部分的服务单独定义在 user boot 这个模块中 将角色 权限对应关系加载到 Redis 木谷博客系统在认证中心颁发令牌的时候是将用户的角色

大家好,我是讯享网,很高兴认识大家。

这节内容说一下木谷博客系统的权限设计,采用现在主流的权限模型RBAC,对应关系如下:


讯享网

以上5张表都在mugu_auth_server这个库中

该部分的服务单独定义在user-boot这个模块中。

将角色、权限对应关系加载到Redis

木谷博客系统在认证中心颁发令牌的时候是将用户的角色保存到令牌中,客户端携带令牌访问服务经过网关层,网关将令牌解析取出角色,然后和资源所需的角色比对,如果包含了,则放行。

问题:如何获取到资源的角色?当然,木谷博客中的资源则是接口。

这里的方式比较粗暴,直接在项目启动加载权限放入redis,代码如下:

@Service public class LoadRolePermissionService { 
    @Autowired private RedisTemplate<String,Object> redisTemplate; @Autowired private SysPermissionService permissionService; / * 初始化权限<->角色对应关系,将其放置到Redis中 */ @PostConstruct public void init(){ 
    //获取所有的权限 List<SysRolePermissionVo> list = permissionService.listRolePermission(); list.parallelStream().peek(k->{ 
    List<String> roles=new ArrayList<>(); if (CollectionUtil.isNotEmpty(k.getRoles())){ 
    for (SysRole role : k.getRoles()) { 
    roles.add(OAuthConstant.ROLE_PREFIX+role.getCode()); } } //放入Redis中 redisTemplate.opsForHash().put(OAuthConstant.OAUTH_URLS,k.getUrl(), roles); }).collect(Collectors.toList()); } } 

讯享网

看下Redis中的数据:

key是接口的URL,由于要满足restful的方式,前面加了请求方式,比如POST,如果不限制请求方式,则为*

value是该接口所需要的角色集合。

网关中只需要从redis中取出接口的角色列表,然后和令牌携带的角色比对,如果存在交集则放行。

com.mugu.blog.gateway.config.JwtAuthorizationManager

讯享网@Override public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) { 
    //匹配url AntPathMatcher antPathMatcher = new AntPathMatcher(); //从Redis中获取当前路径可访问角色列表 URI uri = authorizationContext.getExchange().getRequest().getURI(); //请求方法 POST,GET String method = authorizationContext.getExchange().getRequest().getMethodValue(); / * TODO 为了适配restful接口,比如 GET:/api/.... POST:/api/.... *:/api/..... 星号匹配所有 */ // ① String restFulPath = method + OAuthConstant.METHOD_SUFFIX + uri.getPath(); //② 获取所有的uri->角色对应关系 Map<String, List<String>> entries = redisTemplate.opsForHash().entries(OAuthConstant.OAUTH_URLS); //角色集合 List<String> authorities = new ArrayList<>(); //③  entries.forEach((path, roles) -> { 
    //路径匹配则添加到角色集合中 if (antPathMatcher.match(path, restFulPath)) { 
    authorities.addAll(roles); } }); //认证通过且角色匹配的用户可访问当前路径 return mono //判断是否认证成功 .filter(Authentication::isAuthenticated) //获取认证后的全部权限 .flatMapIterable(Authentication::getAuthorities) .map(GrantedAuthority::getAuthority) // ④ 如果权限包含则判断为true .any(authority->{ 
    //超级管理员直接放行 if (StrUtil.equals(OAuthConstant.ROLE_ROOT_CODE,authority)) return true; //其他必须要判断角色是否存在交集 return CollectionUtil.isNotEmpty(authorities) && authorities.contains(authority); }) .map(AuthorizationDecision::new) .defaultIfEmpty(new AuthorizationDecision(false)); } 

①处的代码将请求的url转换成restful风格

②处的代码从redis中获取接口和角色对应关系集合

③处的代码筛选出当前url的角色集合

④处的代码将token中的角色和url的角色集合比对,存在交集则放行

小讯
上一篇 2025-03-27 09:52
下一篇 2025-03-16 07:11

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/125084.html