從這期開始咱們將主要對Spring Security的另外一個領域Authority,一般被稱爲訪問控制的部分進行說明。 相比較Authentication身份驗證而言,客製化訪問控制的可能性相對會低許多。因此咱們對這部分主要是理解流程和分析設計上的一些動機爲主。 管理訪問控制對大多數讀者來講都都不太陌生,Spring Security基於角色管理的訪問控制學習起來也會較身份驗證來的又有代入感。java
在以前的分享中,咱們已經瞭解了在Spring Security中,對於訪問的身份驗證是經過WebFilter做爲入口。而後調用AuthenticationManager
暴露的驗證服務接口進行驗證的。 一樣的,在驗證身份以後,如訪問受限資源,一樣也會若是身份驗證同樣,被某個WebFilter做爲入口。而後調用一個名爲AccessDecisionManager
的訪問控制決策管理器進行驗證。 web
在Spring Security中,主要關於訪問控制的代碼都被放在了org.springframework.security.access.vote
包中,其中主要的接口分爲三種:spring
AccessDecisionManager
: 負責整個訪問控制受權部分的投票策略和管理;AccessDecisionVoter
: 負責對訪問控制的規則進行表決,是否受權用戶訪問目標資源;ConfigAttribute
: 用於保存相關的訪問控制規則用一句話描述他們的責任就是:AccessDecisionVoter
負責對ConfigAttribute
進行表決,AccessDecsionManager
彙總表決,最終向框架返回最終的受權結果。bash
在一開始,咱們先來回顧下,最先的應用中,咱們是如何進行訪問控制的:框架
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/user").hasRole("USER")
.antMatchers("/user").denyAll()
.and()
.formLogin();
}
複製代碼
咱們經過在configure方法中編寫路徑模式和相應的限定規則來配置整個應用的訪問控制,基於Web表達式的訪問控制規則,除了支持Spring Security中默認提供的一些限制方法之外,也能夠額經過.antMatchers("/user").access("hasRole('USER') or hasRole('ADMIN')")
的access方法加上表達式的形式進行擴展。表達式更是能夠將表達判斷委託給一個Java Class去完成。 好比下方示例代碼就是講表達式的判斷委託給了名爲webSecurity的Bean中的check方法去完成。ide
http
.authorizeRequests()
.antMatchers("/user/**").access("@webSecurity.check(authentication,request)")
...
複製代碼
除了Web表達式之外,Spring Security還提供了幾種進行訪問控制配置的方式,其中最主要的一種即是經過註解在方法級對Controller和Service的方法進行對應的訪問控制的設置。 post
其中Spring Security對應方法級的註解主要又能夠分爲兩類:學習
@Secured
註解 - secured-annotations@PreAuthorize, @PreFilter, @PostAuthorize and @PostFilter
- pre-post-annotations而在Spring Security中以上兩種註解默認是禁用的,咱們須要經過激活配置才能夠進行使用。ui
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
複製代碼
關於相關訪問控制規則的詳細介紹和應用,咱們將在之後的專題中進行逐一說明。當前只是爲未來的分析打一下基礎。spa
AccessDecisionVoter
但是說是整個訪問控制、受權業務的核心。每個AccessDecisionVoter
都須要對它所支持的訪問控制規則進行投票。投票結果只有如下三種狀況:
int ACCESS_GRANTED = 1; // 同意
int ACCESS_ABSTAIN = 0; // 棄權
int ACCESS_DENIED = -1; // 反對
複製代碼
從AccessDecisionVoter
的接口方法簽名能夠看出,其主要兩個方法分別對應的職責一個是判斷是否支持當前的訪問控制規則,另外一個即是對支持的訪問規則進行投票。 在Spring Security提供的AccessDecisionVoter
實現類主要有:
WebExpressionVoter
;RoleVoter
;AuthenticationVoter
。 而三種Voter對應的訪問控制規則又有些略微的不一樣,在身份驗證模塊咱們瞭解到基本上每個AuthenticationProvider
都須要定製化一種AuthenticationToken'。而在訪問控制模塊中,一樣的每個
AccessDecisionVoter也能夠定製化一種
ConfigAttribute。例如,對於
WebExpressionVoter其對應的即是以前提到的
WebExpressionConfigAttribute`。框架提供的AccessDecisionVoter通常能夠知足中小應用下的訪問控制的基本場景。若是咱們當前開發的大型應用有複雜的訪問控制模型,那麼
AccessDecisionVoter
的客製化即是咱們必定會面對的問題,在未來的專題裏咱們會單獨針對如何客製化AccessDecisionVoter
進行說明。
AccessDecisionManager
對於訪問控制業務的做用與AuthenticationManager
對於身份驗證的業務的做用差很少。其中一個即是對暴露了惟一的訪問控制驗證接口。而與AuthenticationManager
不一樣的地方是,在Spring Security中針對AuthenticationManager
只提供了一種ProviderManager
實現類,而AccessDecisionManager
缺由於有不一樣的表決制度分別提供了三種實現類:
AffirmativeBased
一票贊同制UnanimousBased
一票否決制ConsensusBased
少數服從多數Spring Security在默認的配置下使用的AccessDecisionManager
是AffirmativeBased
。若是須要變動的,則能夠經過配置文件修改注入的Bean便可,好比下面的Java Config形式。
@Bean
public AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters
= Arrays.asList(
new WebExpressionVoter(),
new RoleVoter(),
new AuthenticatedVoter()
);
return new UnanimousBased(decisionVoters);
}
複製代碼
對於
AccessDecisionManager
而言,框架提供的的三種表決制度在絕大多數狀況都已經足夠強大。咱們對於其的瞭解便只須要集中在如何配置和管理使用的AccessDecisionVoter
即可。
訪問控制相關一般是咱們使用Spring Security客製化擴展最頻繁的模塊。因此與別的模塊介紹的流程不一樣,本次是先將整個訪問控制模塊的主要接口和組件進行基本的介紹。在後面幾期中,咱們將對每一個組件和其應用進行展開討論。