一般在項目開發中會根據登錄人員的權限大小對接口也會設置權限,那么對接口權限是怎么實現的呢,大多數都是用自定義權限注解,只需要在接口上加上一個注解就可以實現對接口的權限攔截,是否對該接口有權調用
接下來我們用一個簡單的案例測試一下如何實現自定義權限注解
1、首先,創建一個類,命名隨意,這里為MyPermission
package com.study.permission; import java.lang.annotation.*; @Documented //作用域 @Inherited //可繼承 @Target(ElementType.METHOD)//標明自定義注解可作用的地方,指方法 @Retention(RetentionPolicy.RUNTIME) //存活階段,RUNRIME:存在運行期,還有jvm,class文件級別 public @interface MyPermission { String username() default "name"; //是否需要數據權限,默認為true boolean required() default true; }
在此解釋一下,以上類中出現的注解
●@Target注解
Target注解對象范圍:注解可以用於修飾 packages、types(類、接口、枚舉、注解類)、類成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數),它的取值范圍定義在ElementType 枚舉中,詳情可查源碼
●@Retention注解
Reteniton注解的作用是:描述注解保留的時間范圍(被描述的注解在它所修飾的類中可以被保留到何時)
Reteniton注解用來限定那些被它所注解的注解類在注解到其他類上以后,可被保留到何時,一共有三種策略(SOURCE,CLASS,RUNTIME),定義在RetentionPolicy枚舉中
●@Documented注解
Documented注解的作用是:描述在使用 javadoc 工具為類生成幫助文檔時是否要保留其注解信息,有興趣的看官自己去研究研究
●@Inherited注解
Inherited注解的作用是:使被它修飾的注解具有繼承性(如果某個類使用了被@Inherited修飾的注解,則其子類將自動具有該注解),有興趣的看官自己去研究研究
2、創建一個類MyPermissionAspect並繼承Ordered
package com.study.permission; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; import java.lang.reflect.Method; @Component @Aspect public class MyPermissionAspect implements Ordered { @Pointcut("execution(* com.study.controller..*(..))") public void permissionTest() { } @Around("permissionTest()") public Object doPermission(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature)joinPoint.getSignature(); Method method = signature.getMethod(); MyPermission myPermission = method.getAnnotation(MyPermission.class); if(myPermission == null){ return joinPoint.proceed(); } //判斷是否需要數據權限 boolean required = myPermission.required(); if (!required) { return joinPoint.proceed(); } Object[] args = joinPoint.getArgs(); if(null == args || args.length == 0){ return "參數為空"; } JSONObject json = JSONObject.parseObject(String.valueOf(args[0])); String username = json.getString(myPermission.username()); if(!"admin".equals(username)){ return "權限驗證未通過"; } return joinPoint.proceed(); } @Override public int getOrder() { return 0; } }
3、測試demo,在controller層寫測試方法
package com.study.controller; import com.study.permission.MyPermission; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class MainController { @RequestMapping("test") @MyPermission public String permissionTest(@RequestBody String name){ System.out.println("已通過權限"); return "success"; } @RequestMapping("test02") public String permissionTest02(@RequestBody String name){ System.out.println("未加權限"); return "success"; } }
在test方法上加權限注解@MyPermission,用postman測試后,傳入參數name進行判斷攔截,如果是admin則返回success,如果非admin,則顯示權限驗證未通過
加上注解,但傳的參數為非admin時,顯示不通過
測試方法二test02,不加權限注解時,接口應該返回success
寫完了,大致內容就是這樣紫了,但是一般情況下進行權限驗證時候會攜帶token的,通過request獲取token,然后根據token去查詢判斷當前用戶的信息,再進行邏輯判斷,這里全部省略了。。。