从源码看Spring Security的角色和权限之区别

Spring Security中的角色(roles)和权限(authorities)是有区别的。笔者这篇文章将和大家一起从Spring Security源码的角度探讨其区别在何处,以及合理的使用角色和权限,让我们在使用时做到知其然且知其所以然。
项目环境:jdk1.8,Springboot 2.1.0,IntelliJ idea2018
首先我们在内存中定义几个用户。一个用户名为"cj",角色为 “USER"的用户,另一个用户名为"admin”,权限为"admin"的用户。在这里插入图片描述
当然这个方法定义在继承了WebSecurityConfigurerAdapter的自定义WebSecurityConfig类中

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        在内存中定义用户,方便测试使用
        auth
                .inMemoryAuthentication()
                .withUser("cj")
                .password(passwordEncoder().encode("123"))
                .roles("USER")
        .and()
                .withUser("admin")
                .password(passwordEncoder().encode("123"))
                .authorities("admin");
    }

然后我们写一个方法用于用户登录后获取用户信息。在一个Controller中定义如下方法:

 @RequestMapping("getInfo")
    @ResponseBody
    public Authentication getInfo(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication;
    }

启动程序:分别使用用户名cj密码123,用户名admin密码123登录。在浏览器中通过上面定义的getInfo方法获取用户信息。
cj的authentication对象(认证信息)如下图:
在这里插入图片描述
可以很清楚的看到,这个authority字段前面多了一个“ROLE_”,程序中定义的是USER。Why?跟进源码…
在这里插入图片描述
通过阅读源码发现,Spring Security的 public User.UserBuilder roles(String… roles)方法是为了给User附上authorities信息,而且它在赋值的过程中还去判断了程序中开发者设置roles时有没有以“ROLE_”开头,有的话直接赋值。没有的话,呵呵。它自作主张的给role强行加上“ROLE_”前缀。这就是为什么我们获取cj的authentication对象时authority的值为“ROLE_USER”。至于为什么Spring Security的设计师要这样做,我还不清楚(大家谁知道可以留言一下)。
那我们在配置路径认证时的hasROLE()方法,该怎么配置呢。配置成hasRole(“ROLE_USER”)和hasRole(“USER”)都可以,why?跟进源码…
在这里插入图片描述
在判断roleSet.contains(defaultedRole)之前,Spring Security会想调用getRoleWithDefaultPrefix(prefix, role)此方法,继续跟下去。
在这里插入图片描述
Spring Security和之前在roles()方法中设定role时一样,如果没有设置ROLE_开头,强制给hasROLE()方法中的值设置前缀ROLE_,以此来达到跟之前roles()方法中设定的role匹配的目的。
接下来我们一起来看看authorities()方法中设置admin会怎样。用户名admin,密码123登录后,获取认证信息 http://localhost:9999/getInfo (自己的端口号自己定义)。
在这里插入图片描述
可以清楚的看到authority为admin。在配置hasAuthority时只能配置成hasAuthority(“admin”),这里面的源码大家自己跟进去看看。和上面分析的差不多,只是authorties()和hasAuthory()方法都没有关于前缀ROLE_的处理。
从上面的分析可以看出,roles的设定其实就是向user的authorities赋值,只不过多了一步加ROLE_的处理,在认证路径的时候同样多了这一步的处理。
所以我们该如何决定使用roles还是authorities呢,我建议是选择authorities。为什么呢,因为我们在使用数据库中的roles往user赋权限时,必须写成这样new SimpleGrantedAuthority(“ROLE_” + role),也就是和源码中一样必须强制添加前缀ROLE_,才能在使用hasRoles,然而这是不合理的。所以笔者建议使用hasAuthority()方法对路径进行权限控制,这样更有逻辑性。
不求打赏(土豪除外),点赞关注走一走鸭!
在这里插入图片描述
spring security Oauth2 交流群
在这里插入图片描述

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值