日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

通過Spring AOP結合SpEL表達式:構建強大且靈活的權限控制體系

來源: 責編: 時間:2023-11-28 09:36:09 229觀看
導讀環境:SpringBoot2.7.121.前言在當今的Web應用程序中,權限驗證是一個重要的安全措施,用于確保只有具有適當權限的用戶才能訪問特定的資源。隨著應用程序的規模和復雜性的增加,實現權限驗證變得更加困難。為了解決這個問題,

環境:SpringBoot2.7.12Dhm28資訊網——每日最新資訊28at.com

1.前言

在當今的Web應用程序中,權限驗證是一個重要的安全措施,用于確保只有具有適當權限的用戶才能訪問特定的資源。隨著應用程序的規模和復雜性的增加,實現權限驗證變得更加困難。為了解決這個問題,我們可以使用Spring AOP(面向切面編程)和Spring Security的組合,它們可以提供一種有效的方法來實現權限驗證。Dhm28資訊網——每日最新資訊28at.com

在本文中,我們將探討如何使用Spring AOP和Spring Security來實現權限驗證。我們首先介紹Spring AOP和Spring Security的概念,然后解釋如何將它們結合起來實現權限驗證。通過這種方式,我們可以確保只有具有適當權限的用戶能夠訪問受保護的資源,從而提高應用程序的安全性。Dhm28資訊網——每日最新資訊28at.com

一、Spring AOP介紹


Spring AOP是Spring框架中的一個模塊,用于支持面向切面編程。它允許開發者在應用程序中的關鍵點定義切面,從而對程序流程進行干預和控制。通過使用AOP,我們可以將與業務邏輯無關的代碼(如日志記錄、事務管理、權限認證等)抽取出來,并將其放在獨立的切面中,這樣可以提高代碼的可重用性和可維護性。Dhm28資訊網——每日最新資訊28at.com

二、Spring Security介紹


Spring Security是一個強大的安全框架,用于保護Web應用程序。它提供了豐富的安全特性,包括認證、授權、訪問控制等。通過使用Spring Security,我們可以輕松地實現用戶身份驗證、角色授權、URL級別的訪問控制等功能,從而確保只有經過授權的用戶才能訪問受保護的資源。Dhm28資訊網——每日最新資訊28at.com

三、Spring AOP與Spring Security的組合


我們可以將Spring AOP與Spring Security結合起來實現權限驗證。具體步驟如下:Dhm28資訊網——每日最新資訊28at.com

  1. 定義一個Aspect切面,用于實現權限驗證邏輯。該Aspect可以攔截用戶對受保護資源的訪問請求,并驗證其權限。
  2. 定義一個Filter,該過濾器實現token的解析,將權限信息保存到當前的安全上下文中,最后添加到Security的過濾器鏈中。
  3. 在Aspect中,我們可以使用Spring Security提供的API來獲取當前用戶的身份信息、角色等信息,并根據業務需求判斷用戶是否具有訪問受保護資源的權限。
  4. 如果用戶沒有足夠的權限訪問受保護資源,我們可以拋出一個異常,以阻止用戶繼續訪問。
  5. 如果用戶具有足夠的權限訪問受保護資源,我們可以允許用戶繼續訪問該資源。

通過這種方式,我們可以輕松地實現權限驗證,從而提高應用程序的安全性。同時,使用Spring AOP和Spring Security還可以降低代碼的耦合度,提高代碼的可重用性和可維護性。Dhm28資訊網——每日最新資訊28at.com

2. 權限認證實現

相關依賴

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-security</artifactId></dependency><dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-aop</artifactId></dependency><dependency>    <groupId>com.auth0</groupId>    <artifactId>java-jwt</artifactId>    <version>4.4.0</version></dependency>

權限認證過濾器

該過濾器的作用用來解析token,將權限信息添加到SecurityContext上下文中Dhm28資訊網——每日最新資訊28at.com

public class PackAuthenticationFilter extends OncePerRequestFilter {  public static final String TOKEN_NAME = "x-api-token" ;    @SuppressWarnings("unused")  private ApplicationContext context ;    public PackAuthenticationFilter(ApplicationContext context) {    this.context = context ;  }    @Override  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)      throws ServletException, IOException {    String token = request.getHeader(TOKEN_NAME) ;    if (!StringUtils.hasLength(token)) {      response.setContentType("text/html;charset=UTF-8") ;      response.getWriter().println("沒有權限訪問") ;      return ;    }     // 解析token    List<? extends GrantedAuthority> authorities = JwtUtils.parseAuthority(token) ;    Authentication authentication = new UsernamePasswordAuthenticationToken("", "", authorities) ;    SecurityContextHolder.getContext().setAuthentication(authentication) ;    filterChain.doFilter(request, response) ;  }}

安全配置類

將上面的過濾器添加到Security過濾器鏈中Dhm28資訊網——每日最新資訊28at.com

@Configurationpublic class SecurityConfig {    @Autowired  void setContext(ApplicationContext context) {    this.context = context ;  }  @Bean  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {    http.csrf().disable();    // 對所有的資源全部放行,我們只做對Controller接口的限制訪問    http.authorizeRequests().anyRequest().permitAll() ;    // 添加過濾器    http.addFilterBefore(new PackAuthenticationFilter(this.context), UsernamePasswordAuthenticationFilter.class) ;    http.formLogin().disable() ;    return http.build();  }}

自定義注解

該注解的作用用來標注具體的Controller接口。Dhm28資訊網——每日最新資訊28at.com

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface PreAuthority {    String value() default "" ;  }

驗證切面

該切面讀取接口配置的權限,驗證是否具有相應的權限Dhm28資訊網——每日最新資訊28at.com

@Component@Aspectpublic class AuthenticationAspect {    private AuthorityVerify authorityVerify ;    public AuthenticationAspect(AuthorityVerify authorityVerify) {    this.authorityVerify = authorityVerify ;  }    @Pointcut("@annotation(auth)")  private void authority(PreAuthority auth) {}    @Around("authority(auth)")  public Object test(ProceedingJoinPoint pjp, PreAuthority auth) throws Throwable {    String authority = auth.value() ;    boolean permit = this.authorityVerify.hasAuthority(authority) ;    if (!permit) {      throw new RuntimeException("權限不足") ;    }    Object ret = pjp.proceed() ;    return ret ;  }  }

權限驗證工具類Dhm28資訊網——每日最新資訊28at.com

@Componentpublic class AuthorityVerify {  public boolean hasAuthority(String authority) {    Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities() ;    return authorities.contains(new SimpleGrantedAuthority(authority)) ;  }  }

全局異常處理

在上面的切面類中,如果沒有權限是直接拋出的異常,所以這里定義一個全局異常對異常進行統一的處理。都比較簡單,理解即可。
Dhm28資訊網——每日最新資訊28at.com

@RestControllerAdvicepublic class GlobalExceptionAdvice {    @ExceptionHandler({Exception.class})  public Object exceptionProcess(Exception e) {    return e.getMessage() ;  }}

測試接口

@RestController@RequestMapping("/api")public class ApiController {  @GetMapping("/save")  @PreAuthority("api:save")  public Object save(HttpServletResponse response) throws Exception {    return "save method invoke..." ;  }    @GetMapping("/{id}")  @PreAuthority("api:query")  public Object query(@PathVariable("id") Integer id) {    return "query method invoke..." ;  }  }

測試用戶Dhm28資訊網——每日最新資訊28at.com

Map<String, Object> map = new HashMap<>() ;map.put("userId", "888888") ;map.put("authorities", List.of("api:create", "api:query", "api:update", "api:delete")) ;String token = createToken(map) ;System.out.println(token) ;String content = parseToken(token);System.out.println(content) ;System.out.println(">>>>>>>>>>>>>>>>>>>>>") ;System.out.println(parseAuthority(token)) ;

這里模擬了一個用戶信息,設置了權限集合,通過這些信息生成JWT信息。如下:Dhm28資訊網——每日最新資訊28at.com

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI4ODg4ODgiLCJhdXRob3JpdGllcyI6WyJhcGk6Y3JlYXRlIiwiYXBpOnF1ZXJ5IiwiYXBpOnVwZGF0ZSIsImFwaTpkZWxldGUiXSwiZXhwIjoxNjk5NjE3NTM3fQ.GGLYIP2g5RZZkBoLnyQ_NWOQq_NUQylr5iZH9ouDiCM

測試結果

圖片圖片Dhm28資訊網——每日最新資訊28at.com

/api/save接口配置的權限是api:save,實際模擬的用戶是沒有這個權限的,所以這里看到的是切面中拋出的異常信息。Dhm28資訊網——每日最新資訊28at.com

圖片圖片Dhm28資訊網——每日最新資訊28at.com

查詢接口正常訪問。Dhm28資訊網——每日最新資訊28at.com

以上是簡單的示例,實際你應該會使用Spring Security結合數據庫一起來驗證管理用戶的。Dhm28資訊網——每日最新資訊28at.com

通過本文的介紹,我們了解了如何使用Spring AOP和Spring Security的組合來實現權限驗證。通過這種方式,我們可以提高應用程序的安全性,并降低代碼的耦合度,提高代碼的可重用性和可維護性。希望本文能夠幫助讀者更好地理解和應用Spring AOP和Spring Security,為他們的應用程序開發提供有益的參考。Dhm28資訊網——每日最新資訊28at.com

思考:

在上面的Controller中直接通過@PreAuthority('xxx')進行權限的設置,那我們是不是可以實現類似Spring Security提供@PreAuthorize("hasRole('xxx')")注解的功能,其中hasRole('xxx')是SpEL表達式。其實這里我們可以對切面稍加修改即可實現,部分代碼如下:Dhm28資訊網——每日最新資訊28at.com

初始化SpEL上下文:Dhm28資訊網——每日最新資訊28at.com

@PostConstructpublic void init() {  SpelParserConfiguration config = new SpelParserConfiguration(true, true);  parser = new SpelExpressionParser(config) ;  context = new StandardEvaluationContext() ;  context.setRootObject(this.authorityVerify) ;}

修改切面

@Around("authority(auth)")public Object test(ProceedingJoinPoint pjp, PreAuthority auth) throws Throwable {  String authority = auth.value() ;  boolean permit = this.parser.parseExpression(authority).getValue(this.context, Boolean.class) ;  if (!permit) {    throw new RuntimeException("不具備對應角色") ;  }  Object ret = pjp.proceed() ;  return ret ;}

修改接口

@GetMapping("/save")@PreAuthority("hasRole({'ADMIN', 'MGR'})")public Object save(HttpServletResponse response) throws Exception {  return "save method invoke..." ;}

該接口只要具有ADMIN或者MGR角色的都可以訪問。Dhm28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-34646-0.html通過Spring AOP結合SpEL表達式:構建強大且靈活的權限控制體系

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 阿里面試官:LinkedHashMap是怎么保證元素有序的?

下一篇: 如何使用 Formik 創建 React 表單

標簽:
  • 熱門焦點
  • 官方承諾:K60至尊版將會首批升級MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版將會搭載天璣9200+處理器和獨顯芯片X7的同時,Redmi給出了官方承諾,K60至尊重大更新首批升級,會首批推送MIUI 15。也就是說雖然
  • Redmi Buds 4開箱簡評:才199還有降噪 可以無腦入

    在上個月舉辦的Redmi Note11T Pro系列新機發布會上,除了兩款手機新品之外,Redmi還帶來了兩款TWS真無線藍牙耳機產品,Redmi Buds 4和Redmi Buds 4 Pro,此前我們在Redmi Note11T
  • Flowable工作流引擎的科普與實踐

    一.引言當我們在日常工作和業務中需要進行各種審批流程時,可能會面臨一系列技術和業務上的挑戰。手動處理這些審批流程可能會導致開發成本的增加以及業務復雜度的上升。在這
  • JavaScript學習 -AES加密算法

    引言在當今數字化時代,前端應用程序扮演著重要角色,用戶的敏感數據經常在前端進行加密和解密操作。然而,這樣的操作在網絡傳輸和存儲中可能會受到惡意攻擊的威脅。為了確保數據
  • 為什么你不應該使用Div作為可點擊元素

    按鈕是為任何網絡應用程序提供交互性的最常見方式。但我們經常傾向于使用其他HTML元素,如 div span 等作為 clickable 元素。但通過這樣做,我們錯過了許多內置瀏覽器的功能。
  • 認真聊聊東方甄選:如何告別低垂的果實

    來源:山核桃作者:財經無忌爆火一年后,俞敏洪和他的東方甄選依舊是頗受外界關心的&ldquo;網紅&rdquo;。7月5日至9日,為期5天的東方甄選&ldquo;甘肅行&rdquo;首次在自有App內直播,
  • 三星Galaxy Z Fold5官方渲染圖曝光:13.4mm折疊厚度依舊感人

    據官方此前宣布,三星將于7月26日在韓國首爾舉辦Unpacked活動,屆時將帶來帶來包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy Z Flip 5、
  • 聯想小新Pad Pro 12.6將要推出,搭載高通驍龍 870 處理器

    聯想小新Pad Pro 12.6將于秋季新品會上推出,官方按照慣例直接在發布會前給出了機型的所有參數。聯想小新 Pad Pro 12.6 將搭載高通驍龍 870 處理器,重量為 5
  • 華為舉行春季智慧辦公新品發布會 首次推出電子墨水屏平板

    北京時間2月27日晚,華為在巴塞羅那舉行春季智慧辦公新品發布會,在海外市場推出之前已經在中國市場上市的筆記本、平板、激光打印機等辦公產品,并首次推出搭載
Top 主站蜘蛛池模板: 桂阳县| 孟连| 牟定县| SHOW| 光山县| 中山市| 广东省| 延川县| 临潭县| 揭阳市| 辽阳市| 金沙县| 当涂县| 边坝县| 尤溪县| 遂昌县| 清涧县| 泾川县| 婺源县| 开江县| 西昌市| 格尔木市| 凤翔县| 青冈县| 辽宁省| 莱阳市| 出国| 霍林郭勒市| 纳雍县| 元阳县| 鹰潭市| 门源| 普安县| 博白县| 平阳县| 古浪县| 晋州市| 莱州市| 隆回县| 玉树县| 阿克|