From fbff086ed95d898b55502556db9948ee08cc1b83 Mon Sep 17 00:00:00 2001
From: shengzhang <2393584716@qq.com>
Date: Sat, 9 Jan 2021 17:24:44 +0800
Subject: [PATCH] =?UTF-8?q?v1.11.0=20=E6=96=B0=E7=89=B9=E6=80=A7=EF=BC=9AA?=
=?UTF-8?q?OP=E6=B3=A8=E8=A7=A3=E9=89=B4=E6=9D=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sa-token-aop/.gitignore | 12 ++++
sa-token-aop/pom.xml | 35 ++++++++++
.../cn/dev33/satoken/aop/SaCheckAspect.java | 67 +++++++++++++++++++
.../main/resources/META-INF/spring.factories | 1 +
.../java/cn/dev33/satoken/stp/StpLogic.java | 65 +++++++++++++++++-
sa-token-demo-springboot/pom.xml | 7 ++
.../main/java/com/pj/test/TestController.java | 15 ++++-
.../main/java/com/pj/test/TestService.java | 26 +++++++
sa-token-doc/doc/index.html | 4 +-
.../interceptor/SaCheckInterceptor.java | 58 ++--------------
10 files changed, 233 insertions(+), 57 deletions(-)
create mode 100644 sa-token-aop/.gitignore
create mode 100644 sa-token-aop/pom.xml
create mode 100644 sa-token-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java
create mode 100644 sa-token-aop/src/main/resources/META-INF/spring.factories
create mode 100644 sa-token-demo-springboot/src/main/java/com/pj/test/TestService.java
diff --git a/sa-token-aop/.gitignore b/sa-token-aop/.gitignore
new file mode 100644
index 00000000..f56feec7
--- /dev/null
+++ b/sa-token-aop/.gitignore
@@ -0,0 +1,12 @@
+target/
+
+node_modules/
+bin/
+.settings/
+unpackage/
+.classpath
+.project
+
+.factorypath
+
+.idea/
\ No newline at end of file
diff --git a/sa-token-aop/pom.xml b/sa-token-aop/pom.xml
new file mode 100644
index 00000000..463be43f
--- /dev/null
+++ b/sa-token-aop/pom.xml
@@ -0,0 +1,35 @@
+
+
+ 4.0.0
+
+
+ cn.dev33
+ sa-token-parent
+ 1.10.0
+
+ jar
+
+ sa-token-aop
+ sa-token-aop
+ sa-token authentication by spring-aop
+
+
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ 1.10.0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+ 2.0.0.RELEASE
+
+
+
+
+
+
diff --git a/sa-token-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java b/sa-token-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java
new file mode 100644
index 00000000..f2c35f2c
--- /dev/null
+++ b/sa-token-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java
@@ -0,0 +1,67 @@
+package cn.dev33.satoken.aop;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+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 cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.stp.StpUtil;
+
+/**
+ * sa-token 基于 Spring Aop 的注解鉴权
+ * @author kong
+ */
+@Aspect
+@Component
+public class SaCheckAspect {
+
+ /**
+ * 底层的 StpLogic 对象
+ */
+ public StpLogic stpLogic = null;
+
+ /**
+ * 创建,并指定一个默认的 StpLogic
+ */
+ public SaCheckAspect() {
+ this.stpLogic = StpUtil.stpLogic;
+ }
+
+ /**
+ * 定义AOP签名 --> (切入所有使用sa-token鉴权注解的方法)
+ */
+ public static final String POINTCUT_SIGN = "@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || "
+ + "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || "
+ + "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)";
+
+ /**
+ * 声明AOP签名
+ */
+ @Pointcut(POINTCUT_SIGN)
+ public void pointcut() {
+ }
+
+ /**
+ * 环绕切入
+ * @param joinPoint 切面对象
+ * @return 底层方法执行后的返回值
+ * @throws Throwable
+ */
+ @Around("pointcut()")
+ public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+ // 注解鉴权
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ stpLogic.checkMethodAnnotation(signature.getMethod());
+ try {
+ // 执行原有逻辑
+ Object obj = joinPoint.proceed();
+ return obj;
+ } catch (Throwable e) {
+ throw e;
+ }
+ }
+
+}
diff --git a/sa-token-aop/src/main/resources/META-INF/spring.factories b/sa-token-aop/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..9c26ddee
--- /dev/null
+++ b/sa-token-aop/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.aop.SaCheckAspect
\ No newline at end of file
diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
index 25a9472e..1e1f9582 100644
--- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
+++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
@@ -1,5 +1,6 @@
package cn.dev33.satoken.stp;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -9,6 +10,10 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import cn.dev33.satoken.SaTokenManager;
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.annotation.SaCheckRole;
+import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.NotLoginException;
@@ -1041,8 +1046,66 @@ public class StpLogic {
return SaTokenManager.getConfig();
}
+
+ // =================== 注解鉴权 ===================
-
+ /**
+ * 对一个Method对象进行注解检查(注解鉴权内部实现)
+ * @param method Method对象
+ */
+ public void checkMethodAnnotation(Method method) {
+
+ // ----------- 验证登录
+ if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) {
+ this.checkLogin();
+ }
+
+ // ----------- 验证角色
+ // 验证方法上的
+ SaCheckRole scr = method.getAnnotation(SaCheckRole.class);
+ if(scr != null) {
+ String[] roleArray = scr.value();
+ if(scr.mode() == SaMode.AND) {
+ this.checkRoleAnd(roleArray);
+ } else {
+ this.checkRoleOr(roleArray);
+ }
+ }
+ // 验证类上的
+ scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class);
+ if(scr != null) {
+ String[] roleArray = scr.value();
+ if(scr.mode() == SaMode.AND) {
+ this.checkRoleAnd(roleArray);
+ } else {
+ this.checkRoleOr(roleArray);
+ }
+ }
+
+ // ----------- 验证权限
+ // 验证方法上的
+ SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class);
+ if(scp != null) {
+ String[] permissionArray = scp.value();
+ if(scp.mode() == SaMode.AND) {
+ this.checkPermissionAnd(permissionArray);
+ } else {
+ this.checkPermissionOr(permissionArray);
+ }
+ }
+ // 验证类上的
+ scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class);
+ if(scp != null) {
+ String[] permissionArray = scp.value();
+ if(scp.mode() == SaMode.AND) {
+ this.checkPermissionAnd(permissionArray);
+ } else {
+ this.checkPermissionOr(permissionArray);
+ }
+ }
+
+ // 验证通过
+ }
diff --git a/sa-token-demo-springboot/pom.xml b/sa-token-demo-springboot/pom.xml
index 2841c58e..9ac5494c 100644
--- a/sa-token-demo-springboot/pom.xml
+++ b/sa-token-demo-springboot/pom.xml
@@ -51,6 +51,13 @@
org.apache.commons
commons-pool2
-->
+
+
+
diff --git a/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java b/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java
index bb3aceef..e47642d8 100644
--- a/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java
+++ b/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java
@@ -3,6 +3,7 @@ package com.pj.test;
import java.util.Date;
import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -218,7 +219,19 @@ public class TestController {
}
- // 测试 浏览器访问: http://localhost:8081/test/test
+ @Autowired
+ TestService TestService;
+
+ // 测试AOP注解鉴权: http://localhost:8081/test/testAOP
+ @RequestMapping("testAOP")
+ public AjaxJson testAOP() {
+ System.out.println("testAOP");
+ TestService.getList();
+ return AjaxJson.getSuccess();
+ }
+
+
+ // 测试 浏览器访问: http://localhost:8081/test/test
@RequestMapping("test")
public AjaxJson test() {
StpUtil.getTokenSession().logout();
diff --git a/sa-token-demo-springboot/src/main/java/com/pj/test/TestService.java b/sa-token-demo-springboot/src/main/java/com/pj/test/TestService.java
new file mode 100644
index 00000000..3410ddc6
--- /dev/null
+++ b/sa-token-demo-springboot/src/main/java/com/pj/test/TestService.java
@@ -0,0 +1,26 @@
+package com.pj.test;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+
+/**
+ * 用来测试AOP注解鉴权
+ * @author kong
+ *
+ */
+@Service
+//@SaCheckLogin
+public class TestService {
+
+ @SaCheckLogin
+ public List getList() {
+ System.out.println("getList");
+ return new ArrayList();
+ }
+
+}
diff --git a/sa-token-doc/doc/index.html b/sa-token-doc/doc/index.html
index b1275a25..786d5d16 100644
--- a/sa-token-doc/doc/index.html
+++ b/sa-token-doc/doc/index.html
@@ -2,11 +2,11 @@
- sa-token 官方文档
+ sa-token
-
+
diff --git a/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaCheckInterceptor.java b/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaCheckInterceptor.java
index 82a47625..1ab9aba2 100644
--- a/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaCheckInterceptor.java
+++ b/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaCheckInterceptor.java
@@ -1,15 +1,13 @@
package cn.dev33.satoken.interceptor;
+import java.lang.reflect.Method;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
-import cn.dev33.satoken.annotation.SaCheckLogin;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
@@ -52,56 +50,10 @@ public class SaCheckInterceptor implements HandlerInterceptor {
if (handler instanceof HandlerMethod == false) {
return true;
}
- HandlerMethod method = (HandlerMethod ) handler;
+ Method method = ((HandlerMethod) handler).getMethod();
- // ----------- 验证登录
- if(method.hasMethodAnnotation(SaCheckLogin.class) || method.getBeanType().isAnnotationPresent(SaCheckLogin.class)) {
- stpLogic.checkLogin();
- }
-
- // ----------- 验证角色
- // 验证方法上的
- SaCheckRole scr = method.getMethodAnnotation(SaCheckRole.class);
- if(scr != null) {
- String[] roleArray = scr.value();
- if(scr.mode() == SaMode.AND) {
- stpLogic.checkRoleAnd(roleArray); // 必须全部都有
- } else {
- stpLogic.checkRoleOr(roleArray); // 有一个就行了
- }
- }
- // 验证类上的
- scr = method.getBeanType().getAnnotation(SaCheckRole.class);
- if(scr != null) {
- String[] roleArray = scr.value();
- if(scr.mode() == SaMode.AND) {
- stpLogic.checkRoleAnd(roleArray); // 必须全部都有
- } else {
- stpLogic.checkRoleOr(roleArray); // 有一个就行了
- }
- }
-
- // ----------- 验证权限
- // 验证方法上的
- SaCheckPermission scp = method.getMethodAnnotation(SaCheckPermission.class);
- if(scp != null) {
- String[] permissionArray = scp.value();
- if(scp.mode() == SaMode.AND) {
- stpLogic.checkPermissionAnd(permissionArray); // 必须全部都有
- } else {
- stpLogic.checkPermissionOr(permissionArray); // 有一个就行了
- }
- }
- // 验证类上的
- scp = method.getBeanType().getAnnotation(SaCheckPermission.class);
- if(scp != null) {
- String[] permissionArray = scp.value();
- if(scp.mode() == SaMode.AND) {
- stpLogic.checkPermissionAnd(permissionArray); // 必须全部都有
- } else {
- stpLogic.checkPermissionOr(permissionArray); // 有一个就行了
- }
- }
+ // 进行验证
+ stpLogic.checkMethodAnnotation(method);
// 通过验证
return true;