- 前言
- 一、实现方法
- 二、使用步骤
- 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



