Spring Security其它權(quán)限校驗(yàn)方式&自定義權(quán)限校驗(yàn)方式
一、其它權(quán)限校驗(yàn)方法(了解)
我們前面都是使用@PreAuthorize注解,然后在在其中使用的是hasAuthority方法進(jìn)行校驗(yàn)。
SpringSecurity還為我們提供了其它方法例如:hasAnyAuthority,hasRole,hasAnyRole等。
這里我們先不急著去介紹這些方法,我們先去理解hasAuthority的原理,然后再去學(xué)習(xí)其他方法你就更容易理解,而不是死記硬背區(qū)別。并且我們也可以選擇定義校驗(yàn)方法,實(shí)現(xiàn)我們自己的校驗(yàn)邏輯。
hasAuthority方法實(shí)際是執(zhí)行到了SecurityExpressionRoot的hasAuthority,大家只要斷點(diǎn)調(diào)試既可知道它內(nèi)部的校驗(yàn)原理。
它內(nèi)部其實(shí)是調(diào)用authentication的getAuthorities方法獲取用戶的權(quán)限列表。然后判斷我們?cè)诮涌谏隙x的權(quán)限是否被包含于用戶的權(quán)限列表,如果有則返回true放行,反之false攔截。
hasAnyAuthority方法可以傳入多個(gè)權(quán)限,只有用戶有其中任意一個(gè)權(quán)限都可以訪問(wèn)對(duì)應(yīng)資源。
@PreAuthorize("hasAnyAuthority('admin','test','system:dept:list')")
public String hello(){
return "hello";
}hasRole要求有對(duì)應(yīng)的角色才可以訪問(wèn),但是它內(nèi)部會(huì)把我們傳入的參數(shù)拼接上 ROLE_ 后再去比較。
所以這種情況下要用用戶對(duì)應(yīng)的權(quán)限也要有 ROLE_ 這個(gè)前綴才可以。
@PreAuthorize("hasRole('system:dept:list')")
public String hello(){
return "hello";
}hasAnyRole 有任意的角色就可以訪問(wèn)。它內(nèi)部也會(huì)把我們傳入的參數(shù)拼接上 ROLE_ 后再去比較。
所以這種情況下要用用戶對(duì)應(yīng)的權(quán)限也要有 ROLE_ 這個(gè)前綴才可以。
@PreAuthorize("hasAnyRole('admin','system:dept:list')")
public String hello(){
return "hello";
}二、自定義權(quán)限校驗(yàn)方法(掌握)
我們也可以定義自己的權(quán)限校驗(yàn)方法,在@PreAuthorize注解中使用我們的方法。
@Component("ex")
public class SGExpressionRoot {
public boolean hasAuthority(String authority) {
//獲取當(dāng)前用戶的權(quán)限
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
List<String> permissions = loginUser.getPermissions();
//判斷用戶權(quán)限集合中是否存在authority
return permissions.contains(authority);
}
}在SPEL表達(dá)式中使用 @ex相當(dāng)于獲取容器中bean的名字未ex的對(duì)象。然后再調(diào)用這個(gè)對(duì)象的
hasAuthority方法
@RequestMapping("/hello")
@PreAuthorize("@ex.hasAuthority('system:dept:list')")
public String hello(){
return "hello";
}三、基于配置的權(quán)限控制
我們也可以在配置類(lèi)中使用使用配置的方式對(duì)資源進(jìn)行權(quán)限控制。
eg:
.antMatchers("/testCors").hasAuthority("system:dept:list222") @Override
protected void configure(HttpSecurity http) throws Exception {
http
//關(guān)閉csrf
.csrf().disable()
//不通過(guò)Session獲取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// 對(duì)于登錄接口 允許匿名訪問(wèn)
.antMatchers("/user/login").anonymous()
.antMatchers("/testCors").hasAuthority("system:dept:list222")
// 除上面外的所有請(qǐng)求全部需要鑒權(quán)認(rèn)證
.anyRequest().authenticated();
//添加過(guò)濾器
http.addFilterBefore(jwtAuthenticationTokenFilter,
UsernamePasswordAuthenticationFilter.class);
//配置異常處理器
http.exceptionHandling()
//配置認(rèn)證失敗處理器
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
//允許跨域
http.cors();
}四、CSRF
CSRF是指跨站請(qǐng)求偽造(Cross-site request forgery),是web常見(jiàn)的攻擊之一。
SpringSecurity去防止CSRF攻擊的方式就是通過(guò)csrf_token。后端會(huì)生成一個(gè)csrf_token,前端發(fā)起請(qǐng)求的時(shí)候需要攜帶這個(gè)csrf_token,后端會(huì)有過(guò)濾器進(jìn)行校驗(yàn),如果沒(méi)有攜帶或者是偽造的就不允許訪問(wèn)。
我們可以發(fā)現(xiàn)CSRF攻擊依靠的是cookie中所攜帶的認(rèn)證信息。但是在前后端分離的項(xiàng)目中我們的認(rèn)證信息其實(shí)是token,而token并不是存儲(chǔ)中cookie中,并且需要前端代碼去把token設(shè)置到請(qǐng)求頭中才可以,所以CSRF攻擊也就不用擔(dān)心了。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于SpringBoot+ElasticSearch實(shí)現(xiàn)文檔智能化檢索的完整指南
Spring Boot是一個(gè)用來(lái)快速開(kāi)發(fā)、運(yùn)行和部署 Spring 應(yīng)用程序的框架,Elasticsearch是一個(gè)開(kāi)源的、分布式的全文搜索,本文給大家介紹了基于SpringBoot+ElasticSearch實(shí)現(xiàn)文檔智能化檢索的完整指南,需要的朋友可以參考下2025-08-08
python中jieba庫(kù)(中文分詞庫(kù))使用安裝教程
這篇文章主要介紹了python中jieba庫(kù)(中文分詞庫(kù))使用安裝教程,jieba庫(kù)是通過(guò)中文詞庫(kù)的方式來(lái)識(shí)別分詞的。它首先利用一個(gè)中文詞庫(kù),通過(guò)詞庫(kù)計(jì)算漢字之間構(gòu)成詞語(yǔ)的關(guān)聯(lián)概率,所以通過(guò)計(jì)算漢字之間的概率,就可以形成分詞的結(jié)果,需要的朋友可以參考下2023-04-04
PowerJob的GridFsManager工作流程源碼解讀
這篇文章主要為大家介紹了PowerJob的GridFsManager工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
ByteArrayOutputStream簡(jiǎn)介和使用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
ByteArrayOutputStream 是字節(jié)數(shù)組輸出流。它繼承于OutputStream。這篇文章主要介紹了ByteArrayOutputStream簡(jiǎn)介和使用,需要的朋友可以參考下2017-05-05
利用Jackson解決Json序列化和反序列化問(wèn)題
Jackson是一個(gè)用于處理Json數(shù)據(jù)的Java庫(kù),它提供了一系列功能,包括Json序列化和反序列化,所以本文就來(lái)講講如何利用利用Jackson解決Json序列化和反序列化的問(wèn)題吧2023-05-05

