springcloud項目實現自定義權限注解進行接口權限驗證


一般在項目開發中會根據登錄人員的權限大小對接口也會設置權限,那么對接口權限是怎么實現的呢,大多數都是用自定義權限注解,只需要在接口上加上一個注解就可以實現對接口的權限攔截,是否對該接口有權調用

接下來我們用一個簡單的案例測試一下如何實現自定義權限注解

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注解的作用是:描述注解的使用范圍
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去查詢判斷當前用戶的信息,再進行邏輯判斷,這里全部省略了。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM