1 其他權(quán)限檢驗(yàn)
我們前面都是使用@PreAuthorize注解录淡,然后在在其中使用的是hasAuthority方法進(jìn)行校驗(yàn)垂蜗。除此之外,spring security還為我們提供了其它方法例如:hasAnyAuthority,hasRole你弦,hasAnyRole等弃衍。
hasAuthority原碼:
hasAuthority方法底層是執(zhí)行了SecurityExpressionRoot類(lèi)的hasAuthority方法呀非,它內(nèi)部其實(shí)是調(diào)用authentication的getAuthorities方法獲取用戶(hù)的權(quán)限列表,然后判斷我們傳入的參數(shù)是否在權(quán)限列表中镜盯。
hasAnyAuthority方法可以傳入多個(gè)權(quán)限岸裙,只要用戶(hù)有其中任意一個(gè)權(quán)限都可以訪問(wèn)對(duì)應(yīng)資源。
hasRole要求有對(duì)應(yīng)的角色才可以訪問(wèn)速缆,但是它內(nèi)部會(huì)把我們傳入的參數(shù)拼接上 ROLE_ 后再去比較降允,所以這種情況下要求用戶(hù)對(duì)應(yīng)的權(quán)限也要有 ROLE_ 這個(gè)前綴才可以。
hasAnyRole有任意的角色就可以訪問(wèn)艺糜,它內(nèi)部也會(huì)把我們傳入的參數(shù)拼接上 ROLE_ 后再去比較剧董,所以這種情況下也要求用戶(hù)對(duì)應(yīng)的權(quán)限也要有 ROLE_ 這個(gè)前綴才可以幢尚。
2 自定義校驗(yàn)方法
自定義自己的權(quán)限校驗(yàn)方法
@Component("ex")
public class GExpressionRoot {
//獲取當(dāng)前用戶(hù)的權(quán)限
public boolean hasAuthority(String authority) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
List<String> permissions = loginUser.getPermissions();
//判斷用戶(hù)權(quán)限集合中是否存在傳入的參數(shù)authority
return permissions.contains(authority);
}
}
在SPEL表達(dá)式中使用 @ex相當(dāng)于獲取容器中bean的名字為ex的對(duì)象,然后再調(diào)用這個(gè)對(duì)象的hasAuthority方法
@GetMapping("hello")
@PreAuthorize("@ex.hasAuthority('system:test:index')")
public String hello() {
return "hello";
}
3 基于配置的權(quán)限控制
我們也可以在配置類(lèi)中使用使用配置的方式對(duì)資源進(jìn)行權(quán)限控制
@Override
protected void configure(HttpSecurity http) throws Exception {
//關(guān)閉csrf
http.csrf().disable()
//不通過(guò)Session獲取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
//對(duì)于登錄接口翅楼,允許匿名訪問(wèn)
.antMatchers("/user/login").anonymous() //匿名訪問(wèn)(未登錄可訪問(wèn)尉剩,登錄后不可訪問(wèn))
//擁有system:test:index權(quán)限才可訪問(wèn)
.antMatchers("/user/hello").hasAuthority("system:test:index")
.anyRequest().authenticated();
//將token過(guò)濾器添加到過(guò)濾器鏈中
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
//配置異常處理器
http.exceptionHandling()
//配置認(rèn)證異常處理器
.authenticationEntryPoint(authenticationEntryPoint)
//配置授權(quán)異常處理器
.accessDeniedHandler(accessDeniedHandler);
//允許跨域
http.cors();
}