使用Spring安全表達(dá)式控制系統(tǒng)功能訪問(wèn)權(quán)限問(wèn)題
一、SPEL表達(dá)式權(quán)限控制
從spring security 3.0開(kāi)始已經(jīng)可以使用spring Expression表達(dá)式來(lái)控制授權(quán),允許在表達(dá)式中使用復(fù)雜的布爾邏輯來(lái)控制訪問(wèn)的權(quán)限。Spring Security可用表達(dá)式對(duì)象的基類是SecurityExpressionRoot。
| 表達(dá)式函數(shù) | 描述 |
|---|---|
| hasRole([role]) | 用戶擁有指定的角色時(shí)返回true (Spring security默認(rèn)會(huì)帶有ROLE_前綴),去除前綴參考Remove the ROLE_ |
| hasAnyRole([role1,role2]) | 用戶擁有任意一個(gè)指定的角色時(shí)返回true |
| hasAuthority([authority]) | 擁有某資源的訪問(wèn)權(quán)限時(shí)返回true |
| hasAnyAuthority([auth1,auth2]) | 擁有某些資源其中部分資源的訪問(wèn)權(quán)限時(shí)返回true |
| permitAll | 永遠(yuǎn)返回true |
| denyAll | 永遠(yuǎn)返回false |
| anonymous | 當(dāng)前用戶是anonymous時(shí)返回true |
| rememberMe | 當(dāng)前用戶是rememberMe用戶返回true |
| authentication | 當(dāng)前登錄用戶的authentication對(duì)象 |
| fullAuthenticated | 當(dāng)前用戶既不是anonymous也不是rememberMe用戶時(shí)返回true |
| hasIpAddress('192.168.1.0/24')) | 請(qǐng)求發(fā)送的IP匹配時(shí)返回true |
部分朋友可能會(huì)對(duì)Authority和Role有些混淆。Authority作為資源訪問(wèn)權(quán)限可大可小,可以是某按鈕的訪問(wèn)權(quán)限(如資源ID:biz1),也可以是某類用戶角色的訪問(wèn)權(quán)限(如資源ID:ADMIN)。當(dāng)Authority作為角色資源權(quán)限時(shí),hasAuthority('ROLE_ADMIN')與hasRole('ADMIN')是一樣的效果。
二、SPEL在全局配置中的使用
我們可以通過(guò)繼承WebSecurityConfigurerAdapter,實(shí)現(xiàn)相關(guān)的配置方法,進(jìn)行全局的安全配置(之前的章節(jié)已經(jīng)講過(guò)) 。下面就為大家介紹一些如何在全局配置中使用SPEL表達(dá)式。
2.1.URL安全表達(dá)式
config.antMatchers("/system/*").access("hasAuthority('ADMIN') or hasAuthority('USER')")
.anyRequest().authenticated();
這里我們定義了應(yīng)用/person/*URL的范圍,只有擁有ADMIN或者USER權(quán)限的用戶才能訪問(wèn)這些person資源。
2.2.安全表達(dá)式中引用bean
這種方式,比較適合有復(fù)雜權(quán)限驗(yàn)證邏輯的情況,當(dāng)Spring Security提供的默認(rèn)表達(dá)式方法無(wú)法滿足我們的需求的時(shí)候。首先我們定義一個(gè)權(quán)限驗(yàn)證的RbacService。
@Component("rbacService")
@Slf4j
public class RbacService {
//返回true表示驗(yàn)證通過(guò)
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
//驗(yàn)證邏輯代碼
return true;
}
public boolean checkUserId(Authentication authentication, int id) {
//驗(yàn)證邏輯代碼
return true;
}
}
對(duì)于"/person/{id}"對(duì)應(yīng)的資源的訪問(wèn),調(diào)用rbacService的bean的方法checkUserId進(jìn)行權(quán)限驗(yàn)證,傳遞參數(shù)為authentication對(duì)象和person的id。該id為PathVariable,以#開(kāi)頭表示。
config.antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)")
.anyRequest().access("@rbacService.hasPermission(request,authentication)");
三、 Method表達(dá)式安全控制
如果我們想實(shí)現(xiàn)方法級(jí)別的安全配置,Spring Security提供了四種注解,分別是@PreAuthorize , @PreFilter , @PostAuthorize 和 @PostFilter
3.1.開(kāi)啟方法級(jí)別注解的配置
在Spring安全配置代碼中,加上EnableGlobalMethodSecurity注解,開(kāi)啟方法級(jí)別安全配置功能。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
3.2 使用PreAuthorize注解
@PreAuthorize 注解適合進(jìn)入方法前的權(quán)限驗(yàn)證。只有擁有ADMIN角色才能訪問(wèn)findAll方法。
@PreAuthorize("hasRole('ADMIN')")
List<Person> findAll();
3.3 使用PostAuthorize注解
@PostAuthorize 在方法執(zhí)行后再進(jìn)行權(quán)限驗(yàn)證,適合根據(jù)返回值結(jié)果進(jìn)行權(quán)限驗(yàn)證。Spring EL 提供返回對(duì)象能夠在表達(dá)式語(yǔ)言中獲取返回的對(duì)象returnObject。下文代碼只有返回值的name等于authentication對(duì)象的name才能正確返回,否則拋出異常。
@PostAuthorize("returnObject.name == authentication.name")
Person findOne(Integer id);
3.4 使用PreFilter注解
PreFilter 針對(duì)參數(shù)進(jìn)行過(guò)濾,下文代碼表示針對(duì)ids參數(shù)進(jìn)行過(guò)濾,只有id為偶數(shù)才能訪問(wèn)delete方法。
//當(dāng)有多個(gè)對(duì)象是使用filterTarget進(jìn)行標(biāo)注
@PreFilter(filterTarget="ids", value="filterObject%2==0")
public void delete(List<Integer> ids, List<String> usernames) {
3.5 使用PostFilter 注解
PostFilter 針對(duì)返回結(jié)果進(jìn)行過(guò)濾,特別適用于集合類返回值,過(guò)濾集合中不符合表達(dá)式的對(duì)象。
@PostFilter("filterObject.name == authentication.name")
List<Person> findAll();
總結(jié)
以上所述是小編給大家介紹的使用Spring安全表達(dá)式控制系統(tǒng)功能訪問(wèn)權(quán)限問(wèn)題,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
- Spring的@Scheduled 如何動(dòng)態(tài)更新cron表達(dá)式
- Spring切入點(diǎn)表達(dá)式配置過(guò)程圖解
- Spring AOP中使用args表達(dá)式的方法示例
- Spring表達(dá)式語(yǔ)言SpEL用法詳解
- Spring與Shiro整合及加載權(quán)限表達(dá)式問(wèn)題
- Spring實(shí)戰(zhàn)之Bean定義中的SpEL表達(dá)式語(yǔ)言支持操作示例
- Spring實(shí)戰(zhàn)之使用Expression接口進(jìn)行表達(dá)式求值操作示例
- spring aop execution表達(dá)式的用法
相關(guān)文章
通過(guò)java.util.TreeMap源碼加強(qiáng)紅黑樹(shù)的理解
通過(guò)分析java.util.TreeMap源碼來(lái)對(duì)經(jīng)典問(wèn)題紅黑樹(shù)加強(qiáng)理解和理清思路。2017-11-11
關(guān)于JavaEE匿名內(nèi)部類和Lambda表達(dá)式的注意事項(xiàng)
這篇文章主要介紹了關(guān)于JavaEE匿名內(nèi)部類和Lambda表達(dá)式的注意事項(xiàng),匿名內(nèi)部類顧名思義是沒(méi)有修飾符甚至沒(méi)有名稱的內(nèi)部類,使用匿名內(nèi)部類需要注意哪些地方,我們一起來(lái)看看吧2023-03-03
Springcloud中的region和zone的使用實(shí)例
這篇文章主要介紹了Springcloud中的region和zone的使用實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Java輸入流Scanner/BufferedReader使用方法示例
這篇文章主要介紹了Java輸入流Scanner/BufferedReader使用方法,大家看示例吧2013-11-11
JDBC實(shí)現(xiàn)Mysql自動(dòng)重連機(jī)制的方法詳解
最近在工作中發(fā)現(xiàn)了一個(gè)問(wèn)題,通過(guò)查找相關(guān)的資料終于解決了,下面這篇文章主要給大家介紹了關(guān)于JDBC實(shí)現(xiàn)Mysql自動(dòng)重連機(jī)制的相關(guān)資料,文中給出多種解決的方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-07-07
SpringCloud Ribbon負(fù)載均衡工具使用
Ribbon是Netflix的組件之一,負(fù)責(zé)注冊(cè)中心的負(fù)載均衡,有助于控制HTTP和TCP客戶端行為。Spring?Cloud?Netflix?Ribbon一般配合Ribbon進(jìn)行使用,利用在Eureka中讀取的服務(wù)信息,在調(diào)用服務(wù)節(jié)點(diǎn)時(shí)合理進(jìn)行負(fù)載2023-02-02

