Spring Security基於表達式的權限控制

2020-12-13 Java程式設計師之家

Spring Security源碼分析十三:Spring Security 基於表達式的權限控制

Spring Security是一個能夠為基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,為應用系統提供聲明式的安全訪問控制功能,減少了為企業系統安全控制編寫大量重複代碼的工作。

前言

spring security 3.0已經可以使用spring el表達式來控制授權,允許在表達式中使用複雜的布爾邏輯來控制訪問的權限。

常見的表達式

Spring Security可用表達式對象的基類是SecurityExpressionRoot。

表達式描述hasRole([role])用戶擁有制定的角色時返回true (Spring security 默認會帶有ROLE_前綴),去除參考Remove the ROLE_hasAnyRole([role1,role2])用戶擁有任意一個制定的角色時返回truehasAuthority([authority])等同於hasRole,但不會帶有ROLE_前綴hasAnyAuthority([auth1,auth2])等同於hasAnyRolepermitAll永遠返回truedenyAll永遠返回falseanonymous當前用戶是anonymous時返回truerememberMe當前勇士是rememberMe用戶返回trueauthentication當前登錄用戶的authentication對象fullAuthenticated當前用戶既不是anonymous也不是rememberMe用戶時返回truehasIpAddress('192.168.1.0/24'))請求發送的IP匹配時返回true部分代碼:

...... private String defaultRolePrefix = "ROLE_"; //ROLE_前綴 /** Allows "permitAll" expression */ public final boolean permitAll = true; //全部true /** Allows "denyAll" expression */ public final boolean denyAll = false; //全部false public final boolean permitAll() { return true; } public final boolean denyAll() { return false; } public final boolean isAnonymous() { //是否是anonymous return trustResolver.isAnonymous(authentication); } public final boolean isRememberMe(){ //是否是rememberme return trustResolver.isRememberMe(authentication); } ......

URL安全表達式

onfig.antMatchers("/person/*").access("hasRole('ADMIN') or hasRole('USER')") .anyRequest().authenticated();這裡我們定義了應用/person/*URL的範圍,該URL只針對擁有ADMIN或者USER權限的用戶有效。

在Web安全表達式中引用bean

config.antMatchers("/person/*").access("hasRole('ADMIN') or hasRole('USER')") .antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)") .anyRequest() .access("@rbacService.hasPermission(request,authentication)");RbacServiceImpl

@Component("rbacService") @Slf4j public class RbacServiceImpl implements RbacService { /** * uri匹配工具 */ private AntPathMatcher antPathMatcher = new AntPathMatcher(); @Override public boolean hasPermission(HttpServletRequest request, Authentication authentication) { log.info("【RbacServiceImpl】 --hasPermission={}", authentication.getPrincipal()); Object principal = authentication.getPrincipal(); boolean hasPermission = false; //有可能是匿名的anonymous if (principal instanceof SysUser) { //admin永遠放回true if (StringUtils.equals("admin", ((SysUser) principal).getUsername())) { hasPermission = true; } else { //讀取用戶所擁有權限所有的URL 在這裡全部返回true Set<String> urls = new HashSet<>(); for (String url : urls) { if (antPathMatcher.match(url, request.getRequestURI())) { hasPermission = true; break; } } } } return hasPermission; } public boolean checkUserId(Authentication authentication, int id) { return true; } }效果如下:

user-gold-cdn.xitu.io/2018/1/30/1…

Method安全表達式

針對方法級別的訪問控制比較複雜,Spring Security提供了四種註解,分別是@PreAuthorize , @PreFilter , @PostAuthorize 和 @PostFilter

使用method註解

開啟方法級別註解的配置@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class MerryyouSecurityConfig extends WebSecurityConfigurerAdapter {配置相應的bean@Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean @ConditionalOnMissingBean(PasswordEncoder.class) public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); }在方法上面使用註解/** * 查詢所有人員 */ @PreAuthorize("hasRole('ADMIN')") @ApiOperation(value = "獲得person列表", notes = "") @GetMapping(value = "/persons") public List<Person> getPersons() { return personService.findAll(); }PreAuthorize

@PreAuthorize 註解適合進入方法前的權限驗證

@PreAuthorize("hasRole('ADMIN')") List<Person> findAll();PostAuthorize

@PostAuthorize 在方法執行後再進行權限驗證,適合驗證帶有返回值的權限。Spring EL 提供 返回對象能夠在表達式語言中獲取返回的對象returnObject。

@PostAuthorize("returnObject.name == authentication.name") Person findOne(Integer id);PreAuthorize 針對參數進行過濾

//當有多個對象是使用filterTarget進行標註 @PreFilter(filterTarget="ids", value="filterObject%2==0") public void delete(List<Integer> ids, List<String> usernames) { ... }PostFilter 針對返回結果進行過濾

@PreAuthorize("hasRole('ADMIN')") @PostFilter("filterObject.name == authentication.name") List<Person> findAll();效果如下:

raw.githubusercontent.com/longfeizhen…

作者名稱:Spring Security

相關焦點

  • 學習學習SpringSecurity
    ;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;
  • SpringSecurity+JWT之基於RBAC模型的權限管理系統
    權限管理是一個幾乎所有後臺系統的都會涉及的一個重要組成部分,可以說是後臺項目的基本功,主要目的是對整個後臺管理系統進行權限的控制,而針對的對象是員工,避免因權限控制缺失或操作不當引發的風險問題,如操作錯誤,數據洩露等問題。
  • Spring boot + Spring Security實現權限管理
    基於Spring boot + Spring Security實現第一版傳統架構本文是實訓邦的權限管理SpringSecurity+JWT的一個講義,分享給粉絲學習。任務案例分析權限管理是一個幾乎所有後臺系統的都會涉及的一個重要組成部分,可以說是後臺項目的基本功,主要目的是對整個後臺管理系統進行權限的控制,而針對的對象是員工,避免因權限控制缺失或操作不當引發的風險問題,如操作錯誤,數據洩露等問題。
  • SpringSecurity + JWT,從入門到精通!
    RBAC 全稱為基於角色的權限控制,本段將會從什麼是 RBAC,模型分類,什麼是權限,用戶組的使用,實例分析等幾個方面闡述 RBAC思維導圖繪製思維導圖如下什麼是 RBACRBAC 全稱為用戶角色權限控制,通過角色關聯用戶,角色關聯權限,這種方式,間階的賦予用戶的權限,如下圖所示
  • Spring Security實戰乾貨:基於註解的接口角色訪問控制
    在上一篇 基於配置的接口角色訪問控制 我們講解了如何通過 javaConfig 的方式配置接口的角色訪問控制。其實還有一種更加靈活的配置方式 基於註解 。今天我們就來探討一下。DEMO 獲取方式在文末。2.
  • 船新「漲薪秘籍」阿里巴巴內部爆款頂配版Spring Security筆記
    Spring SecuritySpring Security是一個能夠為基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。由於它是Spring生態系統中的一員,因此它伴隨著整個Spring生態系統不斷修正、升級,在spring boot項目中加入springsecurity更是十分簡單,使用Spring Security 減少了為企業系統安全控制編寫大量重複代碼的工作。
  • Spring Boot Security 詳解
    </groupId> <artifactId>spring-boot-starter-security</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId>
  • springboot+springsecurity實現前後端分離簡單實現!
    通過各種方式學習springsecurity,在B站、騰訊課堂、網易課堂、慕課網沒有springsecurity的前後端分離的教學視頻,那我就去csdn去尋找springsecurity博客,發現幾個問題:要麼就是前後端不分離,要麼就是通過內存方式讀取數據,而不是通過資料庫的方式讀取數據,要麼就是大佬們給的代碼不全、把代碼講的太繞,關鍵部分沒有注釋
  • 網際網路安全下的Spring Security之初體驗
    Spring的企業應用系統安全訪問控制解決方案的安全框架,從名字我們也可以看出來它和Spring有著千絲萬縷的關係,所以它可以和Spring進行無縫集成,對於Web應用的安全性,如用戶認證(是否是合法用戶)和用戶授權(是否具有某種權限)SpringSecurity都提供了很好支持,並且支持自定義,給開發人員提供了更大的靈活性。
  • 超全的springboot+springsecurity實現前後端分離簡單實現!
    通過各種方式學習springsecurity,在B站、騰訊課堂、網易課堂、慕課網沒有springsecurity的前後端分離的教學視頻,那我就去csdn去尋找springsecurity博客,發現幾個問題:  實在不行我又跑去github上找開源項目學習,github由於是外國網站,國內訪問速度有點慢!!
  • spring security 整合 springboot 入門案例
    序言前面我們學習了 spring security 與 springmvc 的整合入門教程。這一節我們來學習一下 spring security 與 springboot 整合,為了力求簡單,此處不演示資料庫相關操作。
  • ...Security 的擴展性就非常棒,我們既可以使用 Spring Security...
    表達式控制 URL 路徑權限 表達式控制方法權限 使用過濾註解 動態權限四種方式,我們分別來看。1.表達式控制 URL 路徑權限首先我們來看第一種,就是通過表達式控制 URL 路徑權限,這種方式松哥在之前的文章中實際上和大家講過,這裡我們再來稍微複習一下。
  • Spring Security接管Swagger認證授權,我發現僅用了3行關鍵代碼!
    以Maven為例,向pom.xml文件添加如下配置信息:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId
  • javaEE開發必用的技術 ssm框架+shiro框架實現權限控制及認證
    本文將使用spring,springmvc,mybatis,shiro都是最新版本的框架+JDK1.8完成用戶登錄模塊的DEMO,該DEMO具備較完善的功能,大部分項目都要做權限控制,大部分項目的思路都可以用來參照。
  • Spring Security 5.1 GA 正式發布! - OSCHINA - 中文開源技術交流...
    -->    <dependency>        <groupId>org.springframework.security</groupId>        <artifactId>spring-security-web</artifactId>        <version>5.1.0.RELEASE</version
  • SpringSecurity退出功能實現的正確方式
    一、logout最簡及最佳實踐其實使用Spring Security進行logout非常簡單,只需要在spring Security配置類配置項上加上這樣一行代碼:http.logout()。關於spring Security配置類的其他很多實現、如:HttpBasic模式、formLogin模式、自定義登錄驗證結果、使用權限表達式、session會話管理,在本號的之前的文章已經都寫過了。本節的核心內容就是在原有配置的基礎上,加上這樣一行代碼:http.logout()。
  • 「SpringSecurity-1」Springboot+Security+Oauth2授權碼模式
    話不多說開始搞……項目搭建項目中使用到的相關框架的版本號:springboot版本:2.3.0.RELEASEspring-security-oauth2版本:2.3.3.RELEASE創建認證伺服器添加依賴pom.xml中添加依賴,特別說明這是一個父子項目,父pom中添加了spring-boot-dependencies
  • Shiro權限管理框架入門到實戰
    Shiro的作用用戶訪問權限控制和登陸的認證,1.用於用戶登陸的驗證,2.用戶用戶登錄後的授權,也就是那些用戶擁有訪問那些接口的權限可以響應認證、訪問控制,或者 Session 生命周期中發生的事件可將一個或以上用戶安全數據源數據組合成一個複合的用戶「view」(視圖)支持提供「Remember Me」服務,當用戶第二次登陸時只要session還可用就不需要再次登陸Shiro的優點靈活——Apache
  • SpringSecurity代碼實現JWT接口權限授予與校驗
    一、環境準備工作建立Spring Boot項目併集成了Spring Security,項目可以正常啟動通過controller寫一個HTTP的GET方法服務接口,比如:「/hello」實現最基本的動態數據驗證及權限分配,即實現UserDetailsService接口和UserDetails接口。
  • renren-security v2.0.0 發布,輕量級權限管理系統
    renren-security經歷了2個月的需求整理,功能開發,終於發布了renren-security v2.0.0版本,現可按需加載