亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringAOP實現(xiàn)自定義接口權限控制

 更新時間:2023年11月06日 10:34:34   作者:禿了也弱了。  
本文主要介紹了SpringAOP實現(xiàn)自定義接口權限控制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、接口鑒權方案分析

1、接口鑒權方案

目前大部分接口鑒權方案,一般都是采用 【用戶-角色-權限】模型。

將接口與權限進行編碼死綁定,同時角色與權限進行動態(tài)綁定,用戶與角色也進行動態(tài)綁定。

2、角色分配權限樹

創(chuàng)建用戶之后,用戶可以分配多個角色。

創(chuàng)建角色之后,通過查詢代碼內置的權限樹,進行角色與權限綁定,存入數據庫中

二、編碼實戰(zhàn)

1、定義權限樹與常用方法

使用枚舉進行權限的定義,通過四級權限樹,將權限分為模塊、單元、功能級、接口。接口權限精細分配:

/**
 * 接口權限枚舉定義類
 */
public enum AuthPermission {
    /**
     * 四級權限樹
     * 1 模塊
     * - 2 功能
     * - - 3 接口集(一般是Controller)
     * - - - 4 具體接口(@RequestMapping)
     *
     */

    // 用戶管理
    User("user", "用戶", Type.Module),

    SysUser(User, "系統(tǒng)用戶", Type.Unit),
    SysUserManager(SysUser, "系統(tǒng)用戶管理", Type.Bunch),
    SysUserManagerSelect(SysUserManager, "系統(tǒng)用戶查詢", Type.Function),
    SysUserManagerAdd(SysUserManager, "系統(tǒng)用戶新增", Type.Function),
    SysUserManagerUpdate(SysUserManager, "系統(tǒng)用戶修改", Type.Function),
    SysUserManagerDelete(SysUserManager, "系統(tǒng)用戶刪除", Type.Function),

    NormalUser(User, "普通用戶", Type.Unit),
    NormalUserManager(NormalUser, "普通用戶管理", Type.Bunch),
    NormalUserManagerSelect(NormalUserManager, "普通用戶查詢", Type.Function),
    NormalUserManagerAdd(NormalUserManager, "普通用戶新增", Type.Function),
    NormalUserManagerUpdate(NormalUserManager, "普通用戶修改", Type.Function),
    NormalUserManagerDelete(NormalUserManager, "普通用戶刪除", Type.Function),

    // 訂單管理
    Order("order", "訂單", Type.Module),

    OrderConfirm(Order, "下單管理", Type.Unit),
    OrderConfirmKill(OrderConfirm, "秒殺下單管理", Type.Bunch),
    OrderConfirmKillAdd(OrderConfirmKill, "秒殺訂單新增", Type.Function),
    OrderConfirmKillDelete(OrderConfirmKill, "秒殺訂單刪除", Type.Function),

    OrderConfirmNormal(OrderConfirm, "普通下單管理", Type.Bunch),
    OrderConfirmNormalAdd(OrderConfirmNormal, "普通訂單新增", Type.Function),
    OrderConfirmNormalDelete(OrderConfirmNormal, "普通訂單刪除", Type.Function),

    // ...其他
    ;


    /**
     * 功能權限類型
     */
    public enum Type {
        Module, // 功能模塊
        Unit, // 功能單元
        Bunch, // 功能接口集
        Function, // 功能接口
    }

    // 模塊
    private final String module;
    // 名稱
    private final String title;
    // 父
    private final AuthPermission parent;
    // 類型
    private final Type type;

    AuthPermission(AuthPermission parent, String title, Type type) {
        this(parent.module, parent, title, type);
    }

    AuthPermission(String title, String module, Type type) {
        this(module, null, title, type);
    }

    AuthPermission(String module, AuthPermission parent, String title, Type type) {
        this.module = module;
        this.title = title;
        this.parent = parent;
        this.type = type;
    }

    public String getModule() {
        return module;
    }

    public String getTitle() {
        return title;
    }

    public AuthPermission getParent() {
        return parent;
    }

    public Type getType() {
        return type;
    }
}

import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 接口權限管理類
 */
public class AuthPermissionManagement {

    private static List<AuthArchetype> permissionTree = new ArrayList<>();

    private static Map<AuthPermission, AuthArchetype> permissionMap = new HashMap<>();

    static {
        // 遞歸設置樹
        // 設置子樹
        recursePermissions(permissionTree, permissionMap, null);
    }

    public static void main(String[] args) {
    	// 獲取權限樹(到時候給前端展示樹)
        System.out.println(Json.toJson(getPermissionTree()));

		// 校驗權限
        System.out.println(checkPermission(AuthPermission.NormalUserManagerDelete, AuthPermission.NormalUser));
        System.out.println(checkPermission(AuthPermission.NormalUserManagerDelete, AuthPermission.OrderConfirm));
        System.out.println(checkPermission(AuthPermission.NormalUserManagerDelete, AuthPermission.NormalUserManagerDelete));

    }

    /**
     * 校驗權限 遞歸
     * @param userPermission 用戶角色權限
     * @param interfacePermission 接口權限
     * @return
     */
    public static boolean checkPermission(AuthPermission userPermission, AuthPermission interfacePermission) {
        if (userPermission == interfacePermission) {
            return true;
        }
        // 有子接口權限也可
        AuthArchetype authArchetype = permissionMap.get(interfacePermission);
        if (authArchetype == null) {
            return false;
        }
        return checkChildrenPermission(userPermission, authArchetype);
    }

    private static boolean checkChildrenPermission(AuthPermission userPermission, AuthArchetype authArchetype) {
        if (authArchetype.getName().equals(userPermission.name())) {
            return true;
        }
        if (!CollectionUtils.isEmpty(authArchetype.getSubPermissions())) {
            for (AuthArchetype subPermission : authArchetype.getSubPermissions()) {
                if (subPermission.getName().equals(userPermission.name())) {
                    return true;
                }
                // 遞歸
                if (checkChildrenPermission(userPermission, subPermission)) {
                    return true;
                }
            }
        }
        return false;
    }

    // 獲取權限樹
    public static List<AuthArchetype> getPermissionTree() {
        return permissionTree;
    }

    private static void recursePermissions(List<AuthArchetype> permissionTree, Map<AuthPermission, AuthArchetype> permissionMap, AuthPermission current) {
        for (AuthPermission permission : AuthPermission.values()) {
            if (permission.getParent() == current) {
                AuthArchetype permissionArchetype = new AuthArchetype(permission);
                if (current == null) {
                    permissionTree.add(permissionArchetype);
                } else {
                    permissionMap.get(current).addSubPermission(permissionArchetype);
                }
                permissionMap.put(permission, permissionArchetype);
                recursePermissions(permissionTree, permissionMap, permission);

            }

        }
    }


    public static class AuthArchetype {
        // name
        private String name;
        // 模塊
        private String module;
        // 名稱
        private String title;
        // 父
        private AuthPermission parent;
        // 類型
        private AuthPermission.Type type;
        // 子
        private List<AuthArchetype> subPermissions;

        public AuthArchetype(AuthPermission permission) {
            this.name = permission.name();
            this.module = permission.getModule();
            this.title = permission.getTitle();
            this.parent = permission.getParent();
            this.type = permission.getType();
        }

        public void addSubPermission(AuthArchetype subPermission) {
            if (this.subPermissions == null) {
                this.subPermissions = new ArrayList<>();
            }
            this.subPermissions.add(subPermission);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getModule() {
            return module;
        }

        public void setModule(String module) {
            this.module = module;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public AuthPermission getParent() {
            return parent;
        }

        public void setParent(AuthPermission parent) {
            this.parent = parent;
        }

        public AuthPermission.Type getType() {
            return type;
        }

        public void setType(AuthPermission.Type type) {
            this.type = type;
        }

        public List<AuthArchetype> getSubPermissions() {
            return subPermissions;
        }

        public void setSubPermissions(List<AuthArchetype> subPermissions) {
            this.subPermissions = subPermissions;
        }
    }
}

2、自定義AOP注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {

    AuthPermission[] value() default {};
}

3、AOP切面類(也可以用攔截器實現(xiàn))

import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class AuthAdvice {

    /**
     * 我們希望的是如果方法上有注解,則對方法進行限制,若方法上無注解,單是類上有注解,那么類上的權限注解對該類下所有的接口生效。
     */
    @Around("@annotation(com.qstcloud.athena.opencourse.auth.Auth) || @within(com.qstcloud.athena.opencourse.auth.Auth)")
    public Object preAuth(ProceedingJoinPoint point) throws Throwable {
        if (handleAuth(point)) {
            return point.proceed();
        }
        throw new RuntimeException("權限不足,請求被拒絕");
    }

    /**
     * 邏輯判斷,返回true or false
     * true :權限校驗通過
     * false :權限校驗不通過
     */
    private boolean handleAuth(ProceedingJoinPoint point) {
        MethodSignature ms = point.getSignature() instanceof MethodSignature ? (MethodSignature) point.getSignature() : null;
        Method method = ms.getMethod();
        // 讀取權限注解,優(yōu)先方法上,沒有則讀取類
        Auth Annotation = getAnnotation(method, Auth.class);


        // 判斷權限
        AuthPermission[] authPermissions = Annotation.value();
        if (ArrayUtils.isEmpty(authPermissions)) {
            // 沒有權限樹,登錄就可以訪問
            return checkLogin();
        }
        // 校驗當前登錄用戶,是否包含其中權限之一
        return checkHasPermission(authPermissions);

    }

    /**
     * 校驗當前登錄用戶,是否包含其中權限之一
     */
    private boolean checkHasPermission(AuthPermission[] authPermissions) {
//        User user = UserUtil.getCurrentUser();
//        Role role = user.getRole(); // 獲取角色

        // TODO 判斷角色中的權限,是否包含接口的權限
        return ArrayUtils.contains(authPermissions, AuthPermission.NormalUserManagerUpdate);
    }

    /**
     * 判斷是否登錄
     */
    private boolean checkLogin() {
        // TODO 從redis或者session中判斷是否登錄
        return true;
    }

    /**
     * 讀取權限注解,優(yōu)先方法上,沒有則讀取類
     */
    private Auth getAnnotation(Method method, Class<Auth> authClass) {
        Auth annotation = method.getAnnotation(authClass);
        if (annotation != null) {
            return annotation;
        }

        annotation = method.getDeclaringClass().getAnnotation(authClass);
        return annotation;
    }
}

4、測試一下

@RestController
@RequestMapping("/test")
@Auth
public class TestController {


    @GetMapping("/test1")
    public String test1() {
        return "success";
    }

    @GetMapping("/test2")
    @Auth(AuthPermission.NormalUserManagerDelete)
    public String test2() {
        return "success";
    }

    @GetMapping("/test3")
    @Auth(AuthPermission.NormalUserManagerUpdate)
    public String test3() {
        return "success";
    }
}

 到此這篇關于SpringAOP實現(xiàn)自定義接口權限控制的文章就介紹到這了,更多相關SpringAOP 接口權限控制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • springboot2.2 集成 activity6實現(xiàn)請假流程(示例詳解)

    springboot2.2 集成 activity6實現(xiàn)請假流程(示例詳解)

    這篇文章主要介紹了springboot2.2 集成 activity6實現(xiàn)請假完整流程示例詳解,本文通過示例代碼圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • IDEA中設置Tab健為4個空格的方法

    IDEA中設置Tab健為4個空格的方法

    這篇文章給大家介紹了代碼縮進用空格還是Tab?(IDEA中設置Tab健為4個空格)的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-03-03
  • springboot詳解整合swagger方案

    springboot詳解整合swagger方案

    Swagger是一個規(guī)范和完整的框架,用于生成、描述、調用和可視化?Restful?風格的?Web?服務??傮w目標是使客戶端和文件系統(tǒng)作為服務器以同樣的速度來更新。文件的方法、參數和模型緊密集成到服務器端的代碼,允許API來始終保持同步
    2022-07-07
  • java中BigDecimal進行加減乘除的基本用法

    java中BigDecimal進行加減乘除的基本用法

    大家應該對于不需要任何準確計算精度的數字可以直接使用float或double運算,但是如果需要精確計算的結果,則必須使用BigDecimal類,而且使用BigDecimal類也可以進行大數的操作。下面這篇文章就給大家介紹介紹關于java中BigDecimal進行加減乘除的基本用法。
    2016-12-12
  • Spring Boot Maven 打包可執(zhí)行Jar文件的實現(xiàn)方法

    Spring Boot Maven 打包可執(zhí)行Jar文件的實現(xiàn)方法

    這篇文章主要介紹了Spring Boot Maven 打包可執(zhí)行Jar文件的實現(xiàn)方法,需要的朋友可以參考下
    2018-02-02
  • SpringBoot設置Json返回字段為非空問題

    SpringBoot設置Json返回字段為非空問題

    這篇文章主要介紹了SpringBoot設置Json返回字段為非空問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 如何基于JAVA讀取yml配置文件指定key內容

    如何基于JAVA讀取yml配置文件指定key內容

    這篇文章主要介紹了如何基于JAVA讀取yml配置文件指定key內容,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解

    spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解

    這篇文章主要給大家介紹了關于spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 聲明的相關資料,需要的朋友可以參考下
    2020-08-08
  • java8中Map的一些騷操作總結

    java8中Map的一些騷操作總結

    這篇文章主要給大家介紹了關于java8中Map的一些騷操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • Java精確計算BigDecimal類詳解

    Java精確計算BigDecimal類詳解

    這篇文章主要介紹了Java精確計算BigDecimal類的使用方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12

最新評論