从spring security 3.0开始已经可以使用弹簧表达式表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限.Spring安全可用表达式对象的基类是SecurityExpressionRoot。
表达式函数 描述 hasRole ([role]) 用户拥有指定的角色时返回真实(Spring security默认会带有具备ROLE_前缀),去除前缀参考删除具备ROLE_ hasAnyRole ([role1的角色,role2]) 用户拥有任意一个指定的角色时返回现实 hasAuthority([机构]) 拥有某资源的访问权限时返回现实 hasAnyAuthority ([auth2 auth3]) 拥有某些资源其中部分资源的访问权限时返回现实 permitAll 永远返回现实 denyAll 永远返回错误的 匿名 当前用户是匿名时返回现实 rememberMe 当前用户是rememberMe用户返回现实 身份验证 当前登录用户的身份验证对象 fullAuthenticated 当前用户既不是匿名也不是rememberMe用户时返回现实 hasIpAddress (192.168.1.0/24)) 请求发送的IP匹配时返回现实
部分朋友可能会对权威和作用有些混淆.Authority作为资源访问权限可大可小,可以是某按钮的访问权限(如资源ID: biz1),也可以是某类用户角色的访问权限(如资源ID: ADMIN)。当权威作为角色资源权限时,hasAuthority (ROLE_ADMIN)与hasRole(管理)是一样的效果。
我们可以通过继承WebSecurityConfigurerAdapter,实现相关的配置方法,进行全局的安全配置(之前的章节已经讲过)。下面就为大家介绍一些如何在全局配置中使用?表达式。
2.1.URL安全表达式
config.antMatchers系统("//* ").access (“hasAuthority (“ADMIN”)或hasAuthority(“用户”)”) .authenticated .anyRequest () ();
这里我们定义了应用/人/* URL的范围,只有拥有管理员或用户权者限的用户才能访问这些人资源。
2.2。安全表达式中引用豆
这种方式,比较适合有复杂权限验证逻辑的情况,当Spring Security提供的默认表达式方法无法满足我们的需求的时候,首先我们定义一个权限验证的RbacService。
@ component (“rbacService”) @Slf4j 公开课RbacService {//返回真正的表示验证通过 公共布尔hasPermission (HttpServletRequest请求,验证身份验证){//验证逻辑代码 返回true; } 公共布尔checkUserId(认证认证,int id) {//验证逻辑代码 返回true; } }
对于“/人/{id}”对应的资源的访问,调用rbacService的bean的方法checkUserId进行权限验证,传递参数为身份验证对象和人的id。该id为PathVariable,以#开头表示。
config.antMatchers(“/人/{id}”) .access (“@rbacService.checkUserId(身份验证、# id)”) .anyRequest () .access (“@rbacService.hasPermission(请求,身份验证)”);
如果我们想实现方法级别的安全配置,Spring Security提供了四种注解,分别是@PreAuthorize, @PreFilter, @PostAuthorize和@PostFilter
3.1。开启方法级别注解的配置
在春安全配置代码中,加上EnableGlobalMethodSecurity注解,开启方法级别安全配置功能。
@ configuration @EnableGlobalMethodSecurity (prePostEnabled=true) 公开课MySecurityConfig延伸WebSecurityConfigurerAdapter {
3.2使用PreAuthorize注解
@PreAuthorize注解适合进入方法前的权限验证。只有拥有管理角色才能访问findAll方法。
@PreAuthorize (“hasRole(管理)”) ListfindAll ();
3.3使用PostAuthorize注解
@PostAuthorize在方法执行后再进行权限验证,适合根据返回值结果进行权限验证.Spring EL提供返回对象能够在表达式语言中获取返回的对象returnObject。下文代码只有返回值的名称等于身份验证对象的名字才能正确返回,否则抛出异常。
@PostAuthorize (“returnObject.name==authentication.name”) 人findOne(整数id);
3.4使用预滤器注解