從spring security 3.0
開始已經可使用spring Expression
表達式來控制受權,容許在表達式中使用複雜的布爾邏輯來控制訪問的權限。Spring Security可用表達式對象的基類是SecurityExpressionRoot。git
表達式函數 | 描述 |
---|---|
hasRole([role] ) |
用戶擁有指定的角色時返回true (Spring security 默認會帶有ROLE_ 前綴),去除前綴參考Remove the ROLE_ |
hasAnyRole([role1,role2]) |
用戶擁有任意一個指定的角色時返回true |
hasAuthority([authority]) |
擁有某資源的訪問權限時返回true |
hasAnyAuthority([auth1,auth2]) |
擁有某些資源其中部分資源的訪問權限時返回true |
permitAll |
永遠返回true |
denyAll |
永遠返回false |
anonymous |
當前用戶是anonymous 時返回true |
rememberMe |
當前用戶是rememberMe 用戶返回true |
authentication |
當前登陸用戶的authentication 對象 |
fullAuthenticated |
當前用戶既不是anonymous 也不是rememberMe 用戶時返回true |
hasIpAddress('192.168.1.0/24')) |
請求發送的IP匹配時返回true |
> 部分朋友可能會對Authority和Role有些混淆。Authority做爲資源訪問權限可大可小,能夠是某按鈕的訪問權限(如資源ID:biz1),也能夠是某類用戶角色的訪問權限(如資源ID:ADMIN)。當Authority做爲角色資源權限時,hasAuthority('ROLE_ADMIN')與hasRole('ADMIN')是同樣的效果。github
咱們能夠經過繼承WebSecurityConfigurerAdapter,實現相關的配置方法,進行全局的安全配置(以前的章節已經講過) 。下面就爲你們介紹一些如何在全局配置中使用SPEL表達式。spring
config.antMatchers("/system/*").access("hasAuthority('ADMIN') or hasAuthority('USER')") .anyRequest().authenticated();
這裏咱們定義了應用/person/*
URL的範圍,只有擁有ADMIN
或者USER
權限的用戶才能訪問這些person資源。安全
這種方式,比較適合有複雜權限驗證邏輯的狀況,當Spring Security提供的默認表達式方法沒法知足咱們的需求的時候。首先咱們定義一個權限驗證的RbacService。springboot
@Component("rbacService") @Slf4j public class RbacService { //返回true表示驗證經過 public boolean hasPermission(HttpServletRequest request, Authentication authentication) { //驗證邏輯代碼 return true; } public boolean checkUserId(Authentication authentication, int id) { //驗證邏輯代碼 return true; } }
對於"/person/{id}"對應的資源的訪問,調用rbacService的bean的方法checkUserId進行權限驗證,傳遞參數爲authentication對象和person的id。該id爲PathVariable,以#開頭表示。函數
config.antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)") .anyRequest().access("@rbacService.hasPermission(request,authentication)");
若是咱們想實現方法級別的安全配置,Spring Security
提供了四種註解,分別是@PreAuthorize
, @PreFilter
, @PostAuthorize
和 @PostFilter
學習
在Spring安全配置代碼中,加上EnableGlobalMethodSecurity註解,開啓方法級別安全配置功能。code
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@PreAuthorize 註解適合進入方法前的權限驗證。只有擁有ADMIN角色才能訪問findAll方法。對象
@PreAuthorize("hasRole('ADMIN')") List<person> findAll();
@PostAuthorize 在方法執行後再進行權限驗證,適合根據返回值結果進行權限驗證。Spring EL
提供返回對象可以在表達式語言中獲取返回的對象returnObject
。下文代碼只有返回值的name等於authentication對象的name才能正確返回,不然拋出異常。繼承
@PostAuthorize("returnObject.name == authentication.name") Person findOne(Integer id);
PreFilter 針對參數進行過濾,下文代碼表示針對ids參數進行過濾,只有id爲偶數才能訪問delete方法。
//當有多個對象是使用filterTarget進行標註 @PreFilter(filterTarget="ids", value="filterObject%2==0") public void delete(List<integer> ids, List<string> usernames) {
PostFilter 針對返回結果進行過濾,特別適用於集合類返回值,過濾集合中不符合表達式的對象。
@PostFilter("filterObject.name == authentication.name") List<person> findAll();