1. 程式人生 > >Spring Security使用授權標籤和註解

Spring Security使用授權標籤和註解

Spring Security的宣告式安全授權有兩種方式,一種是以url模式匹配的方式,另一種是方法上使用註解宣告許可權,這裡重點說第二種。

Spring Security預設是禁用註解的,要想開啟註解,需要在繼承WebSecurityConfigurerAdapter的類上加@EnableGlobalMethodSecurity註解,並在該類中將AuthenticationManager定義為Bean。

@Configuration
@EnableWebSecurity
/**
 *  三種方法級許可權控制
 * @author luenxin
 * 1.securedEnabled: Spring Security’s native annotation
 * 2.jsr250Enabled: standards-based and allow simple role-based constraints
 * 3.prePostEnabled: expression-based
 */
@EnableGlobalMethodSecurity(jsr250Enabled=true)
public class CasSecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Autowired
	AuthenticationManager authenticationManager;
}
這樣就啟動了JSR-250的註解支援,我們在方法上使用註解來控制訪問許可權。

一、JSR-250註解

@DenyAll 拒絕所有訪問

@RolesAllowed({"USER", "ADMIN"})  該方法只要具有"USER", "ADMIN"任意一種許可權就可以訪問。這裡可以省略字首ROLE_,實際的許可權可能是ROLE_ADMIN

@PermitAll 允許所有訪問

三種註解在程式碼的註釋裡已經說明了,上邊說的是JSR-250註解,還有一種更強大的是prePostEnabled註解,這是一種基於表示式的註解,並可以自定義擴充套件,只需繼承GlobalMethodSecurityConfiguration類就可以實現。當然,別忘了在該擴充套件類上添加註解:@EnableGlobalMethodSecurity(prePostEnabled = true)來啟動這種註解支援。如果沒有訪問方法的許可權,會丟擲AccessDeniedException。

二、prePostEnabled註解

1、@PreAuthorize:在方法執行之前執行,而且這裡可以呼叫方法的引數,也可以得到引數值,這是利用JAVA8的引數名反射特性,如果沒用JAVA8,那麼也可以利用Spring Security的@P標註引數,或者Spring Data的@Param標註引數。

@PreAuthorize("#userId == authentication.principal.userId or hasAuthority(‘ADMIN’)")

void changePassword(@P("userId") long userId ){  }

這裡表示在changePassword方法執行之前,判斷方法引數userId的值是否等於principal中儲存的當前使用者的userId,或者當前使用者是否具有ROLE_ADMIN許可權,兩種符合其一,就可以訪問該方法。

2、@PostAuthorize:在方法執行之後執行,而且這裡可以呼叫方法的返回值,如果EL為false,那麼該方法也已經執行完了,可能會回滾。EL變數returnObject表示返回的物件。

@PostAuthorize

User getUser("returnObject.userId == authentication.principal.userId or hasPermission(returnObject, 'ADMIN')");

3、@PostFilter:在方法執行之後執行,而且這裡可以呼叫方法的返回值,然後對返回值進行過濾或處理或修改並返回。EL變數returnObject表示返回的物件。只有方法返回的是集合或陣列型別的才可以使用。(與分頁技術不相容)

@postFilter

User getUser("hasPermission(returnObject, 'ADMIN')");

4、@PreFilter:在方法執行之前執行,而且這裡可以呼叫方法的引數,然後對引數值進行過濾或處理或修改,EL變數filterObject表示引數,如有多個引數,使用filterTarget註解引數。只有方法引數是集合或陣列才行。(很少會用到,與分頁技術不相容)