Spring Security 中對於權限控制默認已經提供了不少了,可是,一個優秀的框架必須具有良好的擴展性,剛好,Spring Security 的擴展性就很是棒,咱們既可使用 Spring Security 提供的方式作受權,也能夠自定義受權邏輯。一句話,你想怎麼玩均可以!java
今天鬆哥來和你們介紹一下 Spring Security 中四種常見的權限控制方式。數據庫
四種方式,咱們分別來看。後端
本文是 Spring Security 系列第 30 篇,閱讀前面文章有助於更好的理解本文:跨域
首先咱們來看第一種,就是經過表達式控制 URL 路徑權限,這種方式鬆哥在以前的文章中實際上和你們講過,這裏咱們再來稍微複習一下。安全
Spring Security 支持在 URL 和方法權限控制時使用 SpEL 表達式,若是表達式返回值爲 true 則表示須要對應的權限,不然表示不須要對應的權限。提供表達式的類是 SecurityExpressionRoot:session
能夠看到,SecurityExpressionRoot 有兩個實現類,表示在應對 URL 權限控制和應對方法權限控制時,分別對 SpEL 所作的拓展,例如在基於 URL 路徑作權限控制時,增長了 hasIpAddress 選項。框架
咱們來看下 SecurityExpressionRoot 類中定義的最基本的 SpEL 有哪些:前後端分離
能夠看到,這些都是該類對應的表達式,這些表達式我來給你們稍微解釋下:函數
表達式 | 備註 |
---|---|
hasRole | 用戶具有某個角色便可訪問資源 |
hasAnyRole | 用戶具有多個角色中的任意一個便可訪問資源 |
hasAuthority | 相似於 hasRole |
hasAnyAuthority | 相似於 hasAnyRole |
permitAll | 通通容許訪問 |
denyAll | 通通拒絕訪問 |
isAnonymous | 判斷是否匿名用戶 |
isAuthenticated | 判斷是否定證成功 |
isRememberMe | 判斷是否經過記住我登陸的 |
isFullyAuthenticated | 判斷是否用戶名/密碼登陸的 |
principle | 當前用戶 |
authentication | 從 SecurityContext 中提取出來的用戶對象 |
這是最基本的,在它的繼承類中,還有作一些拓展,我這個我就不重複介紹了。微服務
若是是經過 URL 進行權限控制,那麼咱們只須要按照以下方式配置便可:
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("admin") .antMatchers("/user/**").hasAnyRole("admin", "user") .anyRequest().authenticated() .and() ... }
這裏表示訪問 /admin/**
格式的路徑須要 admin 角色,訪問 /user/**
格式的路徑須要 admin 或者 user 角色。
固然,咱們也能夠經過在方法上添加註解來控制權限。
在方法上添加註解控制權限,須要咱們首先開啓註解的使用,在 Spring Security 配置類上添加以下內容:
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { ... ... }
這個配置開啓了三個註解,分別是:
這三個結合 SpEL 以後,用法很是靈活,這裏和你們稍微分享幾個 Demo。
@Service public class HelloService { @PreAuthorize("principal.username.equals('javaboy')") public String hello() { return "hello"; } @PreAuthorize("hasRole('admin')") public String admin() { return "admin"; } @Secured({"ROLE_user"}) public String user() { return "user"; } @PreAuthorize("#age>98") public String getAge(Integer age) { return String.valueOf(age); } }
ROLE_
前綴。能夠看到,這裏的表達式仍是很是豐富,若是想引用方法的參數,前面加上一個 #
便可,既能夠引用基本類型的參數,也能夠引用對象參數。
缺省對象除了 principal ,還有 authentication(參考第一小節)。
Spring Security 中還有兩個過濾函數 @PreFilter 和 @PostFilter,能夠根據給出的條件,自動移除集合中的元素。
@PostFilter("filterObject.lastIndexOf('2')!=-1") public List<String> getAllUser() { List<String> users = new ArrayList<>(); for (int i = 0; i < 10; i++) { users.add("javaboy:" + i); } return users; } @PreFilter(filterTarget = "ages",value = "filterObject%2==0") public void getAllAge(List<Integer> ages,List<String> users) { System.out.println("ages = " + ages); System.out.println("users = " + users); }
動態權限主要經過重寫攔截器和決策器來實現,這個我在 vhr 的文檔中有過詳細介紹,你們在公衆號【江南一點雨】後臺回覆 888 能夠獲取文檔,我就再也不贅述了。
好啦,今天就喝小夥伴們稍微聊了一下 Spring Security 中的受權問題,固然這裏還有不少細節,後面鬆哥再和你們一一細聊。
若是小夥伴們以爲有收穫,記得點個在看鼓勵下鬆哥哦~