SpringSecurity(十一)許可權表示式和Rbac資料模型
阿新 • • 發佈:2018-11-19
常用表示式
表示式 | 說明 |
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