Spring Security专栏(Security 中的权限和角色) | 您所在的位置:网站首页 › secure用法含义 › Spring Security专栏(Security 中的权限和角色) |
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
写在前面
通过前面几讲的介绍,相信你已经对 Spring Security 中的认证流程有了更全面的了解。认证是实现授权的前提和基础 。 通常我们在执行授权操作时需要明确目标用户,只有明确目标用户才能明确它所具备的角色和权限,用户、角色和权限也是 Spring Security 中所采用的授权模型,所以今天我们来学习Security中的权限和角色。 多说一句 欢迎大家点击我头像查看Security专栏,设计模式专栏已完结。 Spring Security 中的权限和角色我们可以回顾下,配置方法的处理过程位于 WebSecurityConfigurerAdapter 类中,但使用的是另一个 configure(HttpSecurity http) 方法,示例代码如下所示: protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests().anyRequest().authenticated() .and() .formLogin() .and() .httpBasic(); }这是 Spring Security 中作用于访问授权的默认实现方法。 基于权限进行访问控制上图中的 GrantedAuthority 对象代表的就是一种权限对象,而一个 UserDetails 对象具备一个或多个 GrantedAuthority 对象。通过这种关联关系,实际上我们就可以对用户的权限做一些限制,如下所示: 如果用代码来表示这种关联关系,可以采用如下所示的实现方法: UserDetails user = User.withUsername("yn") .password("123456") .authorities("create", "delete") .build();可以看到,这里我们创建了一个名为“jianxiang”的用户,该用户具有“create”和“delete”这两个权限。在 Spring Security 中,提供了一组针对 GrantedAuthority 的配置方法。例如: hasAuthority(String),允许具有特定权限的用户进行访问; hasAnyAuthority(String),允许具有任一权限的用户进行访问。 可以使用上述两个方法来判断用户是否具备对应的访问权限,我们在WebSecurityConfigurerAdapter 的 configure 方法中添加如下代码: @Override protected void configure(HttpSecurity http) throws Exception { http.httpBasic(); http.authorizeRequests().anyRequest().hasAuthority("CREATE"); }这段代码的作用是对于任何请求,只有权限为“CREATE”才能采用访问。如果我们修改一下代码: http.authorizeRequests().anyRequest().hasAnyAuthority("CREATE", "DELETE");此时,只要具备“CREATE”和“DELETE”中任意一种权限的用户都能进行访问。 这两个方法实现起来都比较简单,但局限性也很大,因为我们无法基于一些来自环境和业务的参数灵活控制访问规则。为此,Spring Security 还提供了一个 access() 方法,该方法允许开发人员传入一个表达式进行更加细粒度的权限控制。 这里,我们将引入 SpEL,它是 Spring Expression Language 的简称,是 Spring 框架提供的一种动态表达式语言。基于 SpEL,只要该表达式的返回值是 true,access() 方法就会允许用户访问。如下示例: http.authorizeRequests().anyRequest().access("hasAuthority('CREATE')");上述代码与使用 hasAuthority() 方法的效果是完全一致的,但如果是更为复杂的场景,access() 方法的优势就很明显了。我们可以灵活创建一个表达式,然后通过 access() 方法确定最后的结果,示例代码如下所示: String expression = "hasAuthority('CREATE') and !hasAuthority('Retrieve')"; http.authorizeRequests().anyRequest().access(expression);上述代码的效果是只有拥有“CREATE”权限且不拥有“Retrieve”权限的用户才能进行访问。 基于角色进行访问控制讨论完权限,我们再来看角色,你可以把角色看成是拥有多个权限的一种数据载体,如下图所示,这里我们分别定义了两个不同的角色“User”和“Admin”,它们拥有不同的权限: 讲到这里,你可能会认为 Spring Security 应该提供了一个独立的数据结构来承载角色的含义。但事实上,在 Spring Security 中,并没有定义类似“GrantedRole”这种专门用来定义用户角色的对象,而是复用了 GrantedAuthority 对象。事实上,以“ROLE_”为前缀的 GrantedAuthority 就代表了一种角色,因此我们可以使用如下方式初始化用户的角色: UserDetails user = User.withUsername("yn") .password("123456") .authorities("ROLE_ADMIN") .build();上述代码相当于为用户“jianxiang”指定了“ADMIN”这个角色。为了给开发人员提供更好的开发体验,Spring Security 还提供了另一种简化的方法来指定用户的角色,如下所示 UserDetails user = User.withUsername("yn") .password("123456") .roles("ADMIN") .build();和权限配置一样,Spring Security 也通过使用对应的 hasRole() 和 hasAnyRole() 方法来判断用户是否具有某个角色或某些角色,使用方法如下所示: http.authorizeRequests().anyRequest().hasRole("ADMIN");当然,针对角色,我们也可以使用 access() 方法完成更为复杂的访问控制。而 Spring Security 还提供了其他很多有用的控制方法供开发人员进行灵活使用。作为总结,下表展示了常见的配置方法及其作用: 配置方法作用anonymous()允许匿名访问authenticated()允许认证用户访问denyAll()无条件禁止一切访问hasAnyAuthority(String)允许具有任一权限的用户进行访问hasAnyRole(String)允许具有任一角色的用户进行访问hasAuthority(String)允许具有特定权限的用户进行访问hasIpAddress(String)允许来自特定 IP 地址的用户进行访问hasRole(String)允许具有特定角色的用户进行访问permitAll()无条件允许一切访问Spring Security 中的配置方法列表 好了,今天Security 中的权限和角色就讲到这里。 总结这一讲我们关注的是对请求访问进行授权,而这个过程需要明确 Spring Security 中的用户、权限和角色之间的关联关系。一旦我们对某个用户设置了对应的权限和角色,那么就可以通过各种配置方法来有效控制访问权限。下期我们讲权限的匹配器,下期见,加油。 弦外之音感谢你的阅读,如果你感觉学到了东西,麻烦您点赞,关注。也欢迎有问题我们下面评论交流 加油! 我们下期再见! 给大家分享几个我前面写的几篇骚操作 聊聊不一样的策略模式(值得收藏) copy对象,这个操作有点骚! |
CopyRight 2018-2019 实验室设备网 版权所有 |