Spring Security 中对于权限控制默认已经提供了不少了,可是,一个优秀的框架必须具有良好的扩展性,刚好,Spring Security 的扩展性就很是棒,咱们既可使用 Spring Security 提供的方式作受权,也能够自定义受权逻辑。一句话,你想怎么玩均可以!java
今天松哥来和你们介绍一下 Spring Security 中四种常见的权限控制方式。数据库
四种方式,咱们分别来看。后端
本文是 Spring Security 系列第 30 篇,阅读前面文章有助于更好的理解本文:跨域
首先咱们来看第一种,就是经过表达式控制 URL 路径权限,这种方式松哥在以前的文章中实际上和你们讲过,这里咱们再来稍微复习一下。安全
Spring Security 支持在 URL 和方法权限控制时使用 SpEL 表达式,若是表达式返回值为 true 则表示须要对应的权限,不然表示不须要对应的权限。提供表达式的类是 SecurityExpressionRoot:session
能够看到,SecurityExpressionRoot 有两个实现类,表示在应对 URL 权限控制和应对方法权限控制时,分别对 SpEL 所作的拓展,例如在基于 URL 路径作权限控制时,增长了 hasIpAddress 选项。框架
咱们来看下 SecurityExpressionRoot 类中定义的最基本的 SpEL 有哪些:前后端分离
能够看到,这些都是该类对应的表达式,这些表达式我来给你们稍微解释下:函数
表达式 | 备注 |
---|---|
hasRole | 用户具有某个角色便可访问资源 |
hasAnyRole | 用户具有多个角色中的任意一个便可访问资源 |
hasAuthority | 相似于 hasRole |
hasAnyAuthority | 相似于 hasAnyRole |
permitAll | 通通容许访问 |
denyAll | 通通拒绝访问 |
isAnonymous | 判断是否匿名用户 |
isAuthenticated | 判断是否定证成功 |
isRememberMe | 判断是否经过记住我登陆的 |
isFullyAuthenticated | 判断是否用户名/密码登陆的 |
principle | 当前用户 |
authentication | 从 SecurityContext 中提取出来的用户对象 |
这是最基本的,在它的继承类中,还有作一些拓展,我这个我就不重复介绍了。微服务
若是是经过 URL 进行权限控制,那么咱们只须要按照以下方式配置便可:
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("admin") .antMatchers("/user/**").hasAnyRole("admin", "user") .anyRequest().authenticated() .and() ... }
这里表示访问 /admin/**
格式的路径须要 admin 角色,访问 /user/**
格式的路径须要 admin 或者 user 角色。
固然,咱们也能够经过在方法上添加注解来控制权限。
在方法上添加注解控制权限,须要咱们首先开启注解的使用,在 Spring Security 配置类上添加以下内容:
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { ... ... }
这个配置开启了三个注解,分别是:
这三个结合 SpEL 以后,用法很是灵活,这里和你们稍微分享几个 Demo。
@Service public class HelloService { @PreAuthorize("principal.username.equals('javaboy')") public String hello() { return "hello"; } @PreAuthorize("hasRole('admin')") public String admin() { return "admin"; } @Secured({"ROLE_user"}) public String user() { return "user"; } @PreAuthorize("#age>98") public String getAge(Integer age) { return String.valueOf(age); } }
ROLE_
前缀。能够看到,这里的表达式仍是很是丰富,若是想引用方法的参数,前面加上一个 #
便可,既能够引用基本类型的参数,也能够引用对象参数。
缺省对象除了 principal ,还有 authentication(参考第一小节)。
Spring Security 中还有两个过滤函数 @PreFilter 和 @PostFilter,能够根据给出的条件,自动移除集合中的元素。
@PostFilter("filterObject.lastIndexOf('2')!=-1") public List<String> getAllUser() { List<String> users = new ArrayList<>(); for (int i = 0; i < 10; i++) { users.add("javaboy:" + i); } return users; } @PreFilter(filterTarget = "ages",value = "filterObject%2==0") public void getAllAge(List<Integer> ages,List<String> users) { System.out.println("ages = " + ages); System.out.println("users = " + users); }
动态权限主要经过重写拦截器和决策器来实现,这个我在 vhr 的文档中有过详细介绍,你们在公众号【江南一点雨】后台回复 888 能够获取文档,我就再也不赘述了。
好啦,今天就喝小伙伴们稍微聊了一下 Spring Security 中的受权问题,固然这里还有不少细节,后面松哥再和你们一一细聊。
若是小伙伴们以为有收获,记得点个在看鼓励下松哥哦~