1. 程式人生 > >SpringSecurity(十一)許可權表示式和Rbac資料模型

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<String> 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