SpringSecurity(十一)权限表达式和Rbac数据模型

常用表达式

 
表达式 说明
hasRole([role]) 用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀)
hasAnyRole([role1,role2]) 用户拥有任意一个制定的角色时返回true
hasAuthority([authority]) 等同于hasRole,但不会带有ROLE_前缀
hasAnyAuthority([auth1,auth2]) 等同于hasAnyRole
permitAll 永远返回true
denyAll 永远返回false
authentication 当前登录用户的authentication对象
fullAuthenticated 当前用户既不是anonymous也不是rememberMe用户时返回true
hasIpAddress('192.168.1.0/24')) 请求发送的IP匹配时返回true

 

 

 

 

 

 

 

 

 

 

 

基于URL权限表达式

.antMatchers("/user/**").hasAnyRole("USER") // 需要具有ROLE_USER角色才能访问
.antMatchers("/admin/**").access("hasAnyRole('ADMIN') and hasAnyRole('USER')") // 需要具有ROLE_ADMIN和ROLE_USER角色才能访问

注意:如果需要使用两个权限表达式,则需要通过access()方法。

 

基于RBAC数据模型控制权限

@Component("rbacService")
public class RbacServiceImpl implements RbacService {
    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        Object o = authentication.getPrincipal();
        if (o instanceof UserDetails) {
            String username = ((UserDetails)o).getUsername();
            // 读取用户拥有的资源
            Set urls = new HashSet<>();
            urls.add("/admin/**");
            // 判断用户是否拥有资源
            for (String url : urls) {
                if (antPathMatcher.match(url, request.getRequestURI())) {
                    return true;
                }
            }
        }
        return false;
    }
}

用法

.anyRequest().access("@rbacService.hasPermission(request, authentication)")

 

基于方法的控制表达式

1. 开启使用方法注解的配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

2.四种方法注解:@PreAuthorize、@PostAuthorize、@PreFilter和、PostFilter

3. 用法

@PreAuthorize 注解适合进入方法前的权限验证

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/admin")
    @ResponseBody
    public Object admin(Principal principal) {
        return principal;
    }
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER') and principal.username.equals(#username)")
    @GetMapping("/test/{username}")
    @ResponseBody
    public Object test(@PathVariable String username) {
        return "Hello test";
    }

@PostAuthorize 在方法执行后再进行权限验证,适合验证带有返回值的权限

    // 这里的returnObject就代表返回的对象
    @PostAuthorize("returnObject.username.equals(principal.username)")
    @GetMapping("/demo2")
    public Object demo2() {
        User user = new User("lzc","lzc",AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
        return user;
    }

@PreFilter可以对集合类型的参数进行过滤,@PostFilter可以对集合类型返回值进行过滤,用法跟上面两种方式类似。

 

代码地址    https://github.com/923226145/SpringSecurity/tree/master/chapter11

 

你可能感兴趣的:(SpringBoot,SpringSecurity)