springboot通過AOP和自定義注解實現權限校驗


自定義注解

PermissionCheck:

package com.mgdd.sys.annotation;

import java.lang.annotation.*;

/**
 * @author LWW
 * @site www.lww.com
 * @company
 * @create 2019-12-16 14:08
 */

// 標注這個類它可以標注的位置
@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
// 標注這個注解的注解保留時期
@Retention(RetentionPolicy.RUNTIME)
// 是否生成注解文檔
@Documented
public @interface PermissionCheck {
    //自定義角色值,如果是多個角色,用逗號分割。
    public String role() default "";
}

aop切面類,切到自定義注解PermissionCheck上,當方法上加了注解就會跳進來進行邏輯處理

PermissionCheckAspect:

package com.mgdd.sys.aspect;

import com.mgdd.sys.annotation.PermissionCheck;
import com.mgdd.sys.service.PermissionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author LWW
 * @site www.lww.com
 * @company
 * @create 2019-12-16 14:20
 */
@Aspect
@Component
@Slf4j
public class PermissionCheckAspect {
    @Resource
    private PermissionService permissionService;

    //切入點表達式決定了用注解方式的方法切還是針對某個路徑下的所有類和方法進行切,方法必須是返回void類型
    @Pointcut(value = "@annotation(com.mgdd.sys.annotation.PermissionCheck)")
    private void permissionCheckCut(){};

    //定義了切面的處理邏輯。即方法上加了@PermissionCheck
    @Around("permissionCheckCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        log.info("====================進入AOP============================");
        //1.記錄日志信息
        Signature signature = pjp.getSignature();
        String className = pjp.getTarget().getClass().getSimpleName();
        String methodName = signature.getName();
        log.info("className:{},methodName:{}",className,methodName);

        //2.角色權限校驗
        MethodSignature methodSignature = (MethodSignature)signature;
        Method targetMethod = methodSignature.getMethod();
        if (targetMethod.isAnnotationPresent(PermissionCheck.class)){
            //獲取方法上注解中表明的權限
            PermissionCheck permission =targetMethod.getAnnotation(PermissionCheck.class);
            String role =permission.role();
            log.info("當前接口請求的用戶角色role:{}",role);
            if(StringUtils.isNotEmpty(role)){
                String[] roles = role.split(",");//接口允許的角色
                List<String> list = Arrays.asList(roles);
                //根據id從數據庫中查詢管理員權限(可用前台傳過來的id作為參數)
                List<String> listPermission = permissionService.queryPermission(1);
                //打印管理員權限
                log.info("管理員擁有的權限:"+String.valueOf(listPermission));
                //將注解上標明的權限與查出來的權限進行比對
                for (String l : list){
                    if(!listPermission.contains(l)){
                        log.error("沒有權限");
                        return null;
                    }
                }
                log.info("AOP權限角色校驗通過,進入業務層處理!");
                //3.執行業務邏輯,放行
                return pjp.proceed();
            }
        }
        return "O(∩_∩)O哈哈~";
    }

}

運用,在方法上面加上注解就行

    /**
     * 分頁查詢
     *
     * @param  params 請求參數集
     * @return 結果集封裝對象
     */
    @GetMapping("queryPager")
    @PermissionCheck(role = "sys:user:view")
    public PageUtils queryPager(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        List<Permission> list = permissionService.queryPager(query);
        return new PageUtils(list, query.getTotal());
    }

效果:


免責聲明!

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



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