自定义访问权限控制

项目需要做一些权限访问控制,觉得比较好的方案是AOP+annotation,因为在Java EE的权限控制也是使用类似方式实现。

AccessRight的注解

1
2
3
4
5
6
7
8
9
10
11
12
13
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessRight {
String code();

boolean access() default false;

boolean create() default false;

boolean update() default false;

boolean delete() default false;
}

AccessControlAspect切面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Component //如果不加,spring似乎不会识别这是一个切面
@Aspect
public class AccessControlAspect {
private static final Logger log = Logger
.getLogger(AccessControlAspect.class);

@Pointcut("execution(* xx.*Bean.*()) ")
public void accessControl() {
}

@Around("accessControl()")
public Object checkRight(ProceedingJoinPoint jp) throws Throwable {
String methodName = jp.getSignature().getName();
log.info("check right: " + methodName);
Method method = jp.getTarget().getClass().getDeclaredMethod(methodName);
if (method.isAnnotationPresent(AccessRight.class)) {
AccessRight right = method.getAnnotation(AccessRight.class);
FunctionPermission permission = getRight(right.code());
if (right.access() && permission.hasAccessPermission()) {
log.info("has right to do");
return jp.proceed();
} else {
log.error("no right to do");
}

}
return jp.proceed();
}

private FunctionPermission getRight(String code) {
}
}

applicationContext.xml加如下内容:

1
2
<context:component-scan base-package="xx" />
<aop:aspectj-autoproxy proxy-target-class="false"/> true表示使用cglib代理,否则使用java反射代理

应用在controller中

1
2
3
4
5
6
7
8
9
@Controller
@Scope("request")
public class xxBean {
@AccessRight(code = "something", access = true)
public String foobar() {
log.info("test...");
return "test";
}
}