分享!! 如何自定義許可權校驗的註解並用AOP攔截實現許可權校驗

loopyhz發表於2024-08-18

Customize permission verification annotation and implement it with AOP

詳細步驟

建立自定義註解

image-20240818095410427

自定義如下

image-20240818095509184

解釋一下:

@Target(ElementType.METHOD) // 指定為method上使用的註解
@Retention(RetentionPolicy.RUNTIME) // 在執行時保留
String mustRole() default "" // 註解需要提供一個String型別的引數,不提供的話預設是空字串

接下來使用AOP來攔截寫了這個註解的全部方法

先建立攔截器

image-20240818095936997

具體程式碼如下
程式碼已經逐行寫了註釋進行解釋了,所以直接看註釋就行了

@Aspect
@Component
public class AuthInterceptor {
    
    @Resource
    private UserService userService;   // 後續會使用到,所以注入一下UserService
   
    @Around("@annotation(authCheck)")  // 定義一個環繞通知,根據引數AuthCheck authCheck推斷出需要攔截所有帶有AuthCheck註解的方法
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        String mustRole = authCheck.mustRole(); //拿到被攔截的方法上面的註解中傳入的引數

        //  獲取與當前執行緒關聯的RequestAttributes物件
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();



        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();  // 轉化為HttpServletRequest,拿到當前請求物件
        // 拿到當前登入使用者
        User loginUser = userService.getLoginUser(request);
        // 查詢一下這個被攔截的註解裡面傳進來的引數是不是下面我們自己定義的三種之一
        //USER("使用者", "user"),
   	    //ADMIN("管理員", "admin"),
        // BAN("被封號", "ban");
        UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole);
        // 傳進來的引數不是這三種,那就認為不需要什麼許可權了,直接放行就行了
        if (mustRoleEnum == null) {
            return joinPoint.proceed();
        }
        // 下面是指定了需要許可權的情況
        // 先拿到當前登入使用者的角色,也就是許可權型別
        UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
        // 如果當前登入使用者啥許可權都沒,直接拋異常
        if (userRoleEnum == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 當前登入使用者要是被封號了,直接拋異常
        if (UserRoleEnum.BAN.equals(userRoleEnum)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 下面就是 當前登入有許可權,而且不是被封號這種
        if (UserRoleEnum.ADMIN.equals(mustRoleEnum)) {
            //  假設定義了管理員許可權,來判斷一下使用者是不是管理院許可權
            if (!UserRoleEnum.ADMIN.equals(userRoleEnum)) {
                // 如果使用者不是管理員許可權,拋異常
                throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
            }
        }
        
        // 到這裡說明   透過許可權校驗了
        // 1. 需要管理員許可權,當前登入使用者就是
        // 2. 不需要管理員許可權,當前使用者是使用者許可權或者是管理員許可權 
        return joinPoint.proceed();
    }
}

相關文章