springboot下自定义注解校验数据权限

文章目录

  • 前言
  • 一、实现方法
  • 二、使用步骤
    • 1.自定义注解
    • 2.编写aop逻辑
    • 3.添加校验器
    • 4.注解使用
  • 源码地址


前言

在日常的系统开发中,功能权限和菜单权限是绕不开的话题,其中功能权限可以借助一些开源框架如spring security解决,而数据权限因为和业务紧密相连,实现起来容易使代码变得臃肿,我用注解实现了一个数据权限的校验逻辑,供大家参考。


一、实现方法

自定义一个注解,通过aop对使用改注解的方法进行校验,具体校验结合了spel表达式

二、使用步骤

1.自定义注解

代码如下:

package com.lyh.authdata.annotation;
import java.lang.annotation.*;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface DataAuth {

    String value();
}

2.编写aop逻辑

代码如下:
校验注解中传入的spel表达式,并运算出结果


@Aspect
@Component
public class DataAuthAspect implements  BeanFactoryAware {

    private BeanFactory beanFactory;
    private final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
    private final ExpressionParser expressionParser = new SpelExpressionParser();

    @Around("@annotation(dataAuth)")
    public Object auth(ProceedingJoinPoint point, DataAuth dataAuth){
        try {
            String expression = dataAuth.value();
            if (StringUtils.isBlank(expression)) {
                return point.proceed();
            } else {
                Method method = ((MethodSignature)point.getSignature()).getMethod();
                StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
                evaluationContext.setBeanResolver(new BeanFactoryResolver(this.beanFactory));
                String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method);
                Object[] args = point.getArgs();
                if (parameterNames != null) {
                    for(int i = 0; i < parameterNames.length; ++i) {
                        String paramName = parameterNames[i];
                        evaluationContext.setVariable(paramName, args[i]);
                    }
                }

                Boolean hasDataAuthorize = this.expressionParser.parseExpression(expression).getValue(evaluationContext, Boolean.class);
                if (hasDataAuthorize == null || !hasDataAuthorize) {
                        throw new RuntimeException("没有操作该数据的数据权限!");
                }else {
                   return point.proceed();
                }
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }

    @Override
    public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
        if (beanFactory == null) {
            throw new NullPointerException("beanFactory is marked non-null but is null");
        } else {
            this.beanFactory = beanFactory;
        }
    }
}

3.添加校验器

这里简单写了下,dataId可以隐身为用户的订单id直接的数据,真是情况下是要查询用户权限数据的,可以一种权限数据对应一种校验器。

@Component
public class AuthValidator {

    public boolean hasAuth(String dataId){
        if("1".equals(dataId)){
            return true;
        }else{
            return false;
        }
    }
}

4.注解使用

根据上一步的校验器逻辑得知,如果传入1可以正常访问,传入其他数会抛出异常,大概模拟出用户访问无权限数据的场景

@RequestMapping("/hello1")
@Controller
public class Test1Controller {

    @RequestMapping(value = "hello1",method = RequestMethod.GET)
    @ResponseBody
    @DataAuth("@authValidator.hasAuth(#dataId)")
    public String hello(@RequestParam String dataId){
      return "hello";
    }
    
}

源码地址

https://download.csdn.net/download/liujevon1212/85438767

你可能感兴趣的:(spring,boot,java,spring)