欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot如何通過(guò)自定義注解實(shí)現(xiàn)權(quán)限檢查詳解

 更新時(shí)間:2020年10月15日 10:21:14   作者:溪源的奇思妙想  
這篇文章主要給大家介紹了關(guān)于SpringBoot如何通過(guò)自定義注解實(shí)現(xiàn)權(quán)限檢查的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近開(kāi)發(fā)了一個(gè)接口,完成后準(zhǔn)備自測(cè)時(shí),卻被攔截器攔截了,提示:(AUTH-NO)未能獲得有效的請(qǐng)求參數(shù)!怎么會(huì)這樣呢?

于是我全局搜了這個(gè)提示語(yǔ),結(jié)果發(fā)現(xiàn)它被出現(xiàn)在一個(gè)Aspect類(lèi)當(dāng)中了,并且把一個(gè) @interface 作為了一個(gè)切點(diǎn),原來(lái)這里利用了Spring AOP面向切面的方式進(jìn)行權(quán)限控制。

SpringBoot通過(guò)自定義注解實(shí)現(xiàn)日志打印可參考:SpringBoot通過(guò)自定義注解實(shí)現(xiàn)日志打印

正文

Spring AOP

Spring AOP 即面向切面,是對(duì)OOP面向?qū)ο蟮囊环N延伸。

AOP機(jī)制可以讓開(kāi)發(fā)者把業(yè)務(wù)流程中的通用功能抽取出來(lái),單獨(dú)編寫(xiě)功能代碼。在業(yè)務(wù)流程執(zhí)行過(guò)程中,Spring框架會(huì)根據(jù)業(yè)務(wù)流程要求,自動(dòng)把獨(dú)立編寫(xiě)的功能代碼切入到流程的合適位置。

我們通過(guò)AOP機(jī)制可以實(shí)現(xiàn):Authentication 權(quán)限檢查、Caching 緩存、Context passing 內(nèi)容傳遞、Error handling 錯(cuò)誤處理、日志打印等功能,這里我們講一下怎么用Spring AOP來(lái)實(shí)現(xiàn)權(quán)限檢查。

SpringBoot 通過(guò)自定義注解實(shí)現(xiàn)權(quán)限檢查

Maven依賴(lài)

<!--lombok-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <optional>true</optional>
</dependency>

<!--Spring AOP-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

MyPermissionTag.class自定義注解

  • @Retention: 用來(lái)修飾注解,是注解的注解,稱(chēng)為元注解。
  • @Target:用來(lái)說(shuō)明對(duì)象的作用范圍
/**
 * 用戶請(qǐng)求權(quán)限校驗(yàn)
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyPermissionTag {
 String value() default "";
 String name() default "";
}

這里特別講一下@Retention,按生命周期來(lái)劃分可分為3類(lèi):

  • RetentionPolicy.SOURCE:注解只保留在源文件,當(dāng)Java文件編譯成class文件的時(shí)候,注解被遺棄(運(yùn)行時(shí)去動(dòng)態(tài)獲取注解信息);
  • RetentionPolicy.CLASS:注解被保留到class文件,但jvm加載class文件時(shí)候被遺棄,這是默認(rèn)的生命周期(在編譯時(shí)進(jìn)行一些預(yù)處理操作);
  • RetentionPolicy.RUNTIME:注解不僅被保存到class文件中,jvm加載class文件之后,仍然存在(做一些檢查性的操作);

這3個(gè)生命周期分別對(duì)應(yīng)于:Java源文件(.java文件) —> .class文件 —> 內(nèi)存中的字節(jié)碼。

AuthInterceptor 權(quán)限檢查的切面

這里簡(jiǎn)單介紹一下,切面的執(zhí)行方法和其執(zhí)行順序:

  • @Around 通知方法將目標(biāo)方法封裝起來(lái)
  • @Before 通知方法會(huì)在目標(biāo)方法調(diào)用之前執(zhí)行
  • @After 通知方法會(huì)在目標(biāo)方法返回或者異常后執(zhí)行
  • @AfterReturning 通知方法會(huì)在目標(biāo)方法返回時(shí)執(zhí)行
  • @Afterthrowing 通知方法會(huì)在目標(biāo)方法拋出異常時(shí)執(zhí)行

這里以一個(gè)返回正常的情況為例:(異常替換最后一步即可)

AuthInterceptor.class

注意要在啟動(dòng)類(lèi)掃描這個(gè)class,并且添加 @EnableAspectJAutoProxy(proxyTargetClass = true)

@Slf4j
@Aspect
@Component
public class AuthInterceptor {


 /**
 * 參數(shù)處理
 *
 * @param point
 */
 @Before("@annotation(com.luo.common.tag.MyPermissionTag)")
 public void beforeProReq(JoinPoint point) {
 log.info("前置攔截-開(kāi)始");
 Request req = getOperationRequest(point.getArgs());
 if (req != null) {
  //解密帳號(hào)
  log.info("前置攔截-開(kāi)始解密ACCOUNT:{}", req.getAccount());


  log.info("前置攔截-結(jié)束解密ACCOUNT:{}", req.getAccount());
 }
 log.info("前置攔截-結(jié)束");
 }


 @Around("@annotation(com.luo.common.tag.MyPermissionTag)")
 public Object authCheck(ProceedingJoinPoint pjp) throws Throwable {
 log.info("權(quán)限攔截-開(kāi)始");
 //請(qǐng)求方法
 ReqMethod reqMethod = getPermissionTag(pjp);


 MyPermissionTag myPermissionTag =reqMethod.perTag;
 log.info(myPermissionTag.value()); //獲取配置的值
 log.info("權(quán)限攔截-開(kāi)始-攔截到方法:{}", reqMethod.getMethodName());


 if("true".equals(myPermissionTag.value().toString())){
  //錯(cuò)誤返回
  Response notGoRes = new Response();
  Request req = getOperationRequest(pjp.getArgs());
  // 校驗(yàn)請(qǐng)求對(duì)象
  if (req == null) {
  notGoRes.setErrorMsg("(AUTH)未能獲得有效的請(qǐng)求參數(shù)!");
  log.info("(AUTH-NO)未能獲得有效的請(qǐng)求參數(shù)!");
  return notGoRes;
  }else {//可以在這里根據(jù)請(qǐng)求參數(shù)對(duì)請(qǐng)求做進(jìn)一步校驗(yàn)


  log.info("完成請(qǐng)求校驗(yàn):"+req);




  }
 }else {
  log.info("未開(kāi)啟權(quán)限校驗(yàn)");
 }


 return pjp.proceed();
 }




 /**
 * 獲取 request 接口中的請(qǐng)求參數(shù)
 * @param args
 * @return
 */
 private Request getOperationRequest(Object[] args) {
 if (args == null || args.length <= 0) {
  log.error("AUTH權(quán)限驗(yàn)證:攔截方法的請(qǐng)求參數(shù)為空!");
  return null;
 }
 Object obj = args[0];
 if (obj instanceof Request) {
  log.info("AUTH權(quán)限驗(yàn)證:請(qǐng)求對(duì)象為正確的OperationRequest對(duì)象");
  return (Request) obj;
 }
 return null;
 }




 /**
 * 獲取攔截的資源標(biāo)簽
 * 這里可以獲取方法名+注解信息(包括 key+value 等)
 * @param pjp
 * @return
 * @throws SecurityException
 * @throws NoSuchMethodException
 */
 private ReqMethod getPermissionTag(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {
 Signature signature = pjp.getSignature();
 MethodSignature methodSignature = (MethodSignature) signature;
 Method targetMethod = methodSignature.getMethod();
 Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());
 MyPermissionTag permissionTag = realMethod.getAnnotation(MyPermissionTag.class);
 return new ReqMethod(permissionTag, realMethod.getName());
 }


 @Setter
 @Getter
 class ReqMethod {


 private MyPermissionTag perTag;
 private String methodName;


 public ReqMethod(MyPermissionTag perTag, String methodName) {
  this.perTag = perTag;
  this.methodName = methodName;
 }


 }
}

驗(yàn)證

測(cè)試接口

@PostMapping("/helloluo")
@MyPermissionTag(value = "true")
public String helloluo(UserPojoReq userPojoReq){
 return "Hello World";
}

發(fā)送請(qǐng)求

驗(yàn)證

總結(jié)

到此這篇關(guān)于SpringBoot如何通過(guò)自定義注解實(shí)現(xiàn)權(quán)限檢查的文章就介紹到這了,更多相關(guān)SpringBoot自定義注解實(shí)現(xiàn)權(quán)限檢查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot整合Dozer實(shí)現(xiàn)深度復(fù)制的方法

    Springboot整合Dozer實(shí)現(xiàn)深度復(fù)制的方法

    Dozer是一種Java?Bean到Java?Bean的映射器,遞歸地將數(shù)據(jù)從一個(gè)對(duì)象復(fù)制到另一個(gè)對(duì)象,它是一個(gè)強(qiáng)大的,通用的,靈活的,可重用的和可配置的開(kāi)源映射框架,本文給大家介紹Springboot整合Dozer的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • Java判斷對(duì)象是否為空(包括null ,

    Java判斷對(duì)象是否為空(包括null ,"")的方法

    這篇文章主要介紹了Java判斷對(duì)象是否為空(包括null ,"")的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Java數(shù)據(jù)脫敏常用方法(3種)

    Java數(shù)據(jù)脫敏常用方法(3種)

    數(shù)據(jù)脫敏常用在電話號(hào)碼和身份證號(hào),本文主要介紹了Java數(shù)據(jù)脫敏常用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • spring event 事件異步處理方式(發(fā)布,監(jiān)聽(tīng),異步處理)

    spring event 事件異步處理方式(發(fā)布,監(jiān)聽(tīng),異步處理)

    這篇文章主要介紹了spring event 事件異步處理方式(發(fā)布,監(jiān)聽(tīng),異步處理),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 分析JVM源碼之Thread.interrupt系統(tǒng)級(jí)別線程打斷

    分析JVM源碼之Thread.interrupt系統(tǒng)級(jí)別線程打斷

    在java編程中,我們經(jīng)常會(huì)調(diào)用Thread.sleep()方法使得線程停止運(yùn)行一段時(shí)間,而Thread類(lèi)中也提供了interrupt方法供我們?nèi)ブ鲃?dòng)打斷一個(gè)線程。那么線程掛起和打斷的本質(zhì)究竟是什么,本文就此問(wèn)題作一個(gè)探究
    2021-06-06
  • 以Json形式的數(shù)據(jù)格式實(shí)現(xiàn)JMeter參數(shù)化

    以Json形式的數(shù)據(jù)格式實(shí)現(xiàn)JMeter參數(shù)化

    本文以小項(xiàng)目學(xué)院管理系統(tǒng)為例,給大家分享以Json形式的數(shù)據(jù)格式實(shí)現(xiàn)JMeter參數(shù)化的相關(guān)知識(shí),包括添加元件操作步驟及使用用戶參數(shù)組件實(shí)現(xiàn)參數(shù)化的方法,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Java實(shí)現(xiàn)斷點(diǎn)下載服務(wù)端與客戶端的示例代碼

    Java實(shí)現(xiàn)斷點(diǎn)下載服務(wù)端與客戶端的示例代碼

    這篇文章主要為大家介紹了如何實(shí)現(xiàn)服務(wù)端(Spring Boot)與客戶端(Android)的斷點(diǎn)下載與下載續(xù)傳功能,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-08-08
  • Javaweb實(shí)現(xiàn)完整個(gè)人博客系統(tǒng)流程

    Javaweb實(shí)現(xiàn)完整個(gè)人博客系統(tǒng)流程

    這篇文章主要介紹了怎樣用Java來(lái)實(shí)現(xiàn)一個(gè)完整的個(gè)人博客系統(tǒng),我們通過(guò)實(shí)操上手的方式可以高效的鞏固所學(xué)的基礎(chǔ)知識(shí),感興趣的朋友一起來(lái)看看吧
    2022-03-03
  • Spring?Boot?使用?SSE?方式向前端推送數(shù)據(jù)詳解

    Spring?Boot?使用?SSE?方式向前端推送數(shù)據(jù)詳解

    這篇文章主要介紹了Spring?Boot?使用SSE方式向前端推送數(shù)據(jù)詳解,SSE簡(jiǎn)單的來(lái)說(shuō)就是服務(wù)器主動(dòng)向前端推送數(shù)據(jù)的一種技術(shù),它是單向的,也就是說(shuō)前端是不能向服務(wù)器發(fā)送數(shù)據(jù)的
    2022-08-08
  • SpringBoot整合MybatisPlus實(shí)現(xiàn)增刪改查功能

    SpringBoot整合MybatisPlus實(shí)現(xiàn)增刪改查功能

    MybatisPlus是國(guó)產(chǎn)的第三方插件,?它封裝了許多常用的CURDapi,免去了我們寫(xiě)mapper.xml的重復(fù)勞動(dòng)。本文將整合MybatisPlus實(shí)現(xiàn)增刪改查功能,感興趣的可以了解一下
    2022-05-05

最新評(píng)論