Customize permission verification annotation and implement it with AOP
詳細步驟
建立自定義註解
自定義如下
解釋一下:
@Target(ElementType.METHOD) // 指定為method上使用的註解
@Retention(RetentionPolicy.RUNTIME) // 在執行時保留
String mustRole() default "" // 註解需要提供一個String型別的引數,不提供的話預設是空字串
接下來使用AOP來攔截寫了這個註解的全部方法
先建立攔截器
具體程式碼如下
程式碼已經逐行寫了註釋進行解釋了,所以直接看註釋就行了
@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();
}
}