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());
    }

效果:

原文地址:https://www.cnblogs.com/liuwenwu9527/p/12113159.html

时间: 2024-11-09 03:03:15

springboot通过AOP和自定义注解实现权限校验的相关文章

spring AOP + 自定义注解实现权限控制小例子

今天看了一下黑马程序员的视频,上面讲到一个使用spring AOP + 自定义注解的方式来实现权限控制的一个小例子,个人觉得还是可以借鉴,整理出来与大家分享. 需求:service层有一些方法,这些方法需要不同的权限才能访问. 实现方案:自定义一个PrivilegeInfo的注解,使用这个注解为service层中的方法进行权限配置,在aop中根据PrivilegeInfo注解的值,判断用户是否拥有访问目标方法的权限,有则访问目标方法,没有则给出提示. 关键技术:自定义注解及注解解析,spring

SpringBoot入门十八,自定义注解的简单实现

项目基本配置参考文章SpringBoot入门一,使用myEclipse新建一个SpringBoot项目,使用myEclipse新建一个SpringBoot项目即可,此示例springboot升级为2.2.1版本. 1. pom.xml添加aop支持 <!-- 引入aop切面支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-

SpringMVC拦截器+Spring自定义注解实现权限验证

设计思路 主要针对需要登录后操作的接口进行校验.接入层在对外暴露接口后,网页.APP.第三方等等途径进行访问接口.用户请求首先会被SpringMVC拦截器拦截到,在拦截器里第一步就是需要校验用户的登录身份(由于是分布式系统这里采用的是userId+accessToken方式来校验),登录校验通过之后再进行用户权限校验,此时会自动拦截@AuthValidate注解的method(核心),如果权限校验失败则抛出权限不足异常,否则校验通过之后再执行具体接口并返回结果. 1.自定义注解 1 packag

通过AOP拦截自定义注解实现相应的功能处理

1.自定义注解 @Retention(RetentionPolicy.RUNTIME)@Target(value={ElementType.METHOD}) public @interface ResultHandle{ Class<?> handler() default ResultHandler.class; } 2.定义方法拦截器实现ResultHandleAnnotationMethodInterceptor实现MethodInterceptor,在invoke方法中对于要执行的方法

struts2拦截器加自定义注解实现权限控制

https://blog.csdn.net/paul342/article/details/51436565 今天结合Java的Annotation和Struts2进行注解拦截器权限控制. 功能需求:添加.查找.删除三个功能,添加.查找功能需进行权限拦截判断,删除功能则不需进行权限拦截判断. 操作流程如下:客户未登录或登录已超时,提示"客户还没登陆或登陆已超时!!!",终止执行,然后跳转到某页面:否则继续往下执行. 以下模拟案例大概实现如上需求,接下来废话少说,直接copy代码 项目地

SpringBoot aop 注解 数据权限校验

注解类: @Retention(RetentionPolicy.RUNTIME) public @interface DataAuthValid { //位置 public int index() default 0; //字段 id //public String id() default "id"; //字段 id public String orgId() default "org_id"; //mapper @SuppressWarnings("r

SpringVC 拦截器+自定义注解 实现权限拦截

1.springmvc配置文件中配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springfr

(转)利用Spring AOP自定义注解解决日志和签名校验

一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!isValid) return ErrorUtil.buildError(ErrorUtil.ERR_CODE_COM

利用Spring AOP自定义注解解决日志和签名校验

转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!