使用AOP+自定義註解完成spring boot的介面許可權校驗

Simpleeee 發表於 2021-09-14
Spring

記使用AOP+自定義註解完成介面的許可權校驗,程式碼如下:

pom檔案新增所需依賴:

1 <dependency>
2     <groupId>org.aspectj</groupId>
3     <artifactId>aspectjrt</artifactId>
4     <version>1.8.9</version>
5 </dependency>
6 <dependency>
7     <groupId>org.springframework.boot</groupId>
8     <artifactId>spring-boot-starter-aop</artifactId>
9 </dependency>

先自定義註解@MyAnnotation註解中可以設定所需引數:

 1 package com.itcq.aop;
 2 
 3 import java.lang.annotation.*;
 4 
 5 //定義註解可以使用的範圍
 6 @Target({ElementType.TYPE, ElementType.METHOD})
 7 @Retention(RetentionPolicy.RUNTIME)
 8 @Documented
 9 public @interface MyAnnotation {
10 
11     String name();
12 }

定義解析註解的MyAnnotationService,完成介面許可權校驗的邏輯,這裡我是獲取介面請求時header中的user_name引數,進行校驗:

 1 package com.itcq.aop;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 import org.aspectj.lang.Signature;
 6 import org.aspectj.lang.annotation.Around;
 7 import org.aspectj.lang.annotation.Aspect;
 8 import org.aspectj.lang.annotation.Pointcut;
 9 import org.springframework.stereotype.Component;
10 import org.springframework.web.context.request.RequestContextHolder;
11 import org.springframework.web.context.request.ServletRequestAttributes;
12 
13 import javax.servlet.http.HttpServletRequest;
14 
15 @Aspect
16 @Component
17 @Slf4j
18 public class MyAnnotationService {
19 
20     //切入點表示式決定了用註解方式的方法切還是針對某個路徑下的所有類和方法進行切,方法必須是返回void型別
21     @Pointcut("@annotation(com.itcq.aop.MyAnnotation)")
22     private void roleCheckCut() {};
23 
24     //定義了切面的處理邏輯。即方法上加了@MyAnnotation註解,將會進行許可權校驗
25     @Around("roleCheckCut()")
26     public Object operateAuth(ProceedingJoinPoint pjp) throws Throwable {
27 
28         //列印日誌
29         Signature signature = pjp.getSignature();
30         String className = pjp.getTarget().getClass().getSimpleName();
31         String methodName = signature.getName();
32         log.info("className:{},methodName:{}", className, methodName);
33 
34         //獲取介面請求時header中的user_name引數,進行校驗
35         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
36         String userName = request.getHeader("user_name");
37         //這裡可以Apollo配置可以放行的角色
38         if (!"hwy".equals(userName)) {
39             throw new Exception(userName+"許可權校驗不通過");
40         }
41         return pjp.proceed();
42     }
43 }

最後在controller層中編寫測試方法,利用postman測試介面:

 1 package com.itcq.controller;
 2 
 3 import com.itcq.aop.MyAnnotation;
 4 import com.itcq.service.TestService;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.web.bind.annotation.GetMapping;
 7 import org.springframework.web.bind.annotation.RequestHeader;
 8 import org.springframework.web.bind.annotation.RequestParam;
 9 import org.springframework.web.bind.annotation.RestController;
10 
11 @RestController
12 public class TestController {
13 
14     @Autowired
15     private TestService testService;
16 
17     @GetMapping("/test")
18     @MyAnnotation(name = "HWY")
19     public String testMethod(@RequestHeader(name = "user_name") String userName,
20                              @RequestParam(name = "user_age") Integer userAge) {
21 
22         return testService.testMethod(userName, userAge);
23     }
24 }

兩種不同請求引數的測試結果如下:

引數正確時的返回結果:

使用AOP+自定義註解完成spring boot的介面許可權校驗

 

 引數不正確時的返回結果,介面報錯,控制檯輸出:

使用AOP+自定義註解完成spring boot的介面許可權校驗

 

 使用AOP+自定義註解完成spring boot的介面許可權校驗

 

 可以發現使用AOP+自定義註解的形式完成了介面的許可權校驗,當然這隻算是比較初級的應用,AOP+自定義註解還有很大的探索空間。