溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring Security基于注解的接口角色訪問(wèn)控制怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2022-04-02 10:57:32 來(lái)源:億速云 閱讀:210 作者:iii 欄目:編程語(yǔ)言

本文小編為大家詳細(xì)介紹“Spring Security基于注解的接口角色訪問(wèn)控制怎么實(shí)現(xiàn)”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Spring Security基于注解的接口角色訪問(wèn)控制怎么實(shí)現(xiàn)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

 Spring Security基于注解的接口角色訪問(wèn)控制怎么實(shí)現(xiàn)

1. 前言

DEMO 獲取方式在文末。

2. Spring Security 方法安全

Spring Security 基于注解的安全認(rèn)證是通過(guò)在相關(guān)的方法上進(jìn)行安全注解標(biāo)記來(lái)實(shí)現(xiàn)的。

2.1 開(kāi)啟全局方法安全

我們可以在任何 @Configuration實(shí)例上使用 @EnableGlobalMethodSecurity 注解來(lái)啟用全局方法安全注解功能。該注解提供了三種不同的機(jī)制來(lái)實(shí)現(xiàn)同一種功能,所以我們單獨(dú)開(kāi)一章進(jìn)行探討。

3. @EnableGlobalMethodSecurity 注解

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)   @Target(value = { java.lang.annotation.ElementType.TYPE })   @Documented   @Import({ GlobalMethodSecuritySelector.class })   @EnableGlobalAuthentication   @Configuration   public @interface EnableGlobalMethodSecurity {       /**        * 基于表達(dá)式進(jìn)行方法訪問(wèn)控制        */       boolean prePostEnabled() default false;       /**        * 基于 @Secured 注解        */       boolean securedEnabled() default false;       /**       * 基于 JSR-250 注解        */       boolean jsr250Enabled() default false;       boolean proxyTargetClass() default false;       int order() default Ordered.LOWEST_PRECEDENCE;   }

@EnableGlobalMethodSecurity 源碼中提供了 prePostEnabled 、securedEnabled 和 jsr250Enabled 三種方式。當(dāng)你開(kāi)啟全局基于注解的方法安全功能時(shí),也就是使用 @EnableGlobalMethodSecurity 注解時(shí)我們需要選擇使用這三種的一種或者其中幾種。我們接下來(lái)將分別介紹它們。

4. 使用 prePostEnabled

如果你在 @EnableGlobalMethodSecurity 設(shè)置 prePostEnabled 為 true ,則開(kāi)啟了基于表達(dá)式的方法安全控制。通過(guò)表達(dá)式運(yùn)算結(jié)果的布爾值來(lái)決定是否可以訪問(wèn)(true 開(kāi)放, false 拒絕 )。

有時(shí)您可能需要執(zhí)行開(kāi)啟 prePostEnabled 復(fù)雜的操作。對(duì)于這些實(shí)例,您可以擴(kuò)展 GlobalMethodSecurityConfiguration,確保子類(lèi)上存在@EnableGlobalMethodSecurity(prePostEnabled = true) 。例如,如果要提供自定義 MethodSecurityExpressionHandler :

@EnableGlobalMethodSecurity(prePostEnabled = true)   public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {       @Override       protected MethodSecurityExpressionHandler createExpressionHandler() {           // ... create and return custom MethodSecurityExpressionHandler ...           return expressionHandler;       }   }

上面示例屬于高級(jí)操作,一般沒(méi)有必要。無(wú)論是否繼承GlobalMethodSecurityConfiguration 都將會(huì)開(kāi)啟四個(gè)注解。 @PreAuthorize 和 @PostAuthorize 側(cè)重于方法調(diào)用的控制;而 @PreFilter 和 @PostFilter 側(cè)重于數(shù)據(jù)的控制。

4.1 @PreAuthorize

在標(biāo)記的方法調(diào)用之前,通過(guò)表達(dá)式來(lái)計(jì)算是否可以授權(quán)訪問(wèn)。接下來(lái)我來(lái)總結(jié)以下常用的表達(dá)式。

  •  基于 SecurityExpressionOperations 接口的表達(dá)式,也就是我們?cè)谏弦晃牡?javaConfig 配置。示例: @PreAuthorize("hasRole('ADMIN')") 必須擁有 ROLE_ADMIN 角色。

  •  基于 UserDetails 的表達(dá)式,此表達(dá)式用以對(duì)當(dāng)前用戶的一些額外的限定操作。示例:@PreAuthorize("principal.username.startsWith('Felordcn')") 用戶名開(kāi)頭為 Felordcn 的用戶才能訪問(wèn)。

  •  基于對(duì)入?yún)⒌?SpEL表達(dá)式處理。 示例: @PreAuthorize("#id.equals(principal.username)") 入?yún)?id 必須同當(dāng)前的用戶名相同。

4.2 @PostAuthorize

在標(biāo)記的方法調(diào)用之后,通過(guò)表達(dá)式來(lái)計(jì)算是否可以授權(quán)訪問(wèn)。該注解是針對(duì) @PreAuthorize 。區(qū)別在于先執(zhí)行方法。而后進(jìn)行表達(dá)式判斷。如果方法沒(méi)有返回值實(shí)際上等于開(kāi)放權(quán)限控制;如果有返回值實(shí)際的結(jié)果是用戶操作成功但是得不到響應(yīng)。

4.3 @PreFilter

基于方法入?yún)⑾嚓P(guān)的表達(dá)式,對(duì)入?yún)⑦M(jìn)行過(guò)濾。分頁(yè)慎用!該過(guò)程發(fā)生在接口接收參數(shù)之前。 入?yún)⒈仨殲?java.util.Collection 且支持 remove(Object) 的參數(shù)。如果有多個(gè)集合需要通過(guò) filterTarget=<參數(shù)名> 來(lái)指定過(guò)濾的集合。內(nèi)置保留名稱(chēng) filterObject 作為集合元素的操作名來(lái)進(jìn)行評(píng)估過(guò)濾。

樣例:

// 入?yún)镃ollection<String> ids   測(cè)試數(shù)據(jù) ["Felordcn","felord","jetty"]  // 過(guò)濾掉  felord jetty  為  Felordcn  @PreFilter(value = "filterObject.startsWith('F')",filterTarget = "ids")  // 如果 當(dāng)前用戶持有 ROLE_AD 角色  參數(shù)都符合  否則 過(guò)濾掉不是 f 開(kāi)頭的     // DEMO 用戶不持有 ROLE_AD 角色  故而 集合只剩下 felord  @PreFilter("hasRole('AD') or filterObject.startsWith('f')")

4.4 @PostFilter

和@PreFilter 不同的是, 基于返回值相關(guān)的表達(dá)式,對(duì)返回值進(jìn)行過(guò)濾。分頁(yè)慎用!該過(guò)程發(fā)生接口進(jìn)行數(shù)據(jù)返回之前。 

5. 使用 securedEnabled

如果你在 @EnableGlobalMethodSecurity 設(shè)置 securedEnabled 為 true ,就開(kāi)啟了角色注解 @Secured ,該注解功能要簡(jiǎn)單的多,默認(rèn)情況下只能基于角色(默認(rèn)需要帶前綴 ROLE_)集合來(lái)進(jìn)行訪問(wèn)控制決策。

該注解的機(jī)制是只要其聲明的角色集合(value)中包含當(dāng)前用戶持有的任一角色就可以訪問(wèn)。也就是 用戶的角色集合和 @Secured 注解的角色集合要存在非空的交集。 不支持使用 SpEL 表達(dá)式進(jìn)行決策。

6. 使用 jsr250Enabled

啟用 JSR-250 安全控制注解,這屬于 JavaEE 的安全規(guī)范(現(xiàn)為 jakarta 項(xiàng)目)。一共有五個(gè)安全注解。如果你在 @EnableGlobalMethodSecurity 設(shè)置 jsr250Enabled 為 true ,就開(kāi)啟了 JavaEE 安全注解中的以下三個(gè):

  •  @DenyAll 拒絕所有的訪問(wèn)

  •  @PermitAll 同意所有的訪問(wèn)

  •  @RolesAllowed 用法和 5. 中的 @Secured 一樣。

讀到這里,這篇“Spring Security基于注解的接口角色訪問(wèn)控制怎么實(shí)現(xiàn)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI