diff --git a/sa-token-demo/sa-token-demo-solon/pom.xml b/sa-token-demo/sa-token-demo-solon/pom.xml
index 21857a8d..0f803e9f 100644
--- a/sa-token-demo/sa-token-demo-solon/pom.xml
+++ b/sa-token-demo/sa-token-demo-solon/pom.xml
@@ -18,7 +18,7 @@
org.noear
solon-web
- 1.9.1
+ 1.9.2
diff --git a/sa-token-starter/sa-token-solon-plugin/pom.xml b/sa-token-starter/sa-token-solon-plugin/pom.xml
index cc9e876a..0f44b91d 100644
--- a/sa-token-starter/sa-token-solon-plugin/pom.xml
+++ b/sa-token-starter/sa-token-solon-plugin/pom.xml
@@ -20,7 +20,7 @@
org.noear
solon
- 1.9.1
+ 1.9.2
diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java
index 65823601..1e7a9786 100644
--- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java
+++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java
@@ -16,8 +16,8 @@ import cn.dev33.satoken.id.SaIdUtil;
import cn.dev33.satoken.json.SaJsonTemplate;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.sign.SaSignTemplate;
-import cn.dev33.satoken.solon.integration.SaContextForSolon;
-import cn.dev33.satoken.solon.integration.SaTokenMethodInterceptor;
+import cn.dev33.satoken.solon.model.SaContextForSolon;
+import cn.dev33.satoken.solon.integration.SaTokenAnnotationInterceptor;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
@@ -31,11 +31,11 @@ public class XPluginImp implements Plugin {
@Override
public void start(AopContext context) {
- context.beanAroundAdd(SaCheckPermission.class, SaTokenMethodInterceptor.INSTANCE);
- context.beanAroundAdd(SaCheckRole.class, SaTokenMethodInterceptor.INSTANCE);
- context.beanAroundAdd(SaCheckLogin.class, SaTokenMethodInterceptor.INSTANCE);
- context.beanAroundAdd(SaCheckSafe.class, SaTokenMethodInterceptor.INSTANCE);
- context.beanAroundAdd(SaCheckBasic.class, SaTokenMethodInterceptor.INSTANCE);
+ context.beanAroundAdd(SaCheckPermission.class, SaTokenAnnotationInterceptor.INSTANCE);
+ context.beanAroundAdd(SaCheckRole.class, SaTokenAnnotationInterceptor.INSTANCE);
+ context.beanAroundAdd(SaCheckLogin.class, SaTokenAnnotationInterceptor.INSTANCE);
+ context.beanAroundAdd(SaCheckSafe.class, SaTokenAnnotationInterceptor.INSTANCE);
+ context.beanAroundAdd(SaCheckBasic.class, SaTokenAnnotationInterceptor.INSTANCE);
//集成初始化
diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenMethodInterceptor.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenAnnotationInterceptor.java
similarity index 74%
rename from sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenMethodInterceptor.java
rename to sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenAnnotationInterceptor.java
index 950b05e2..2f73754c 100644
--- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenMethodInterceptor.java
+++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenAnnotationInterceptor.java
@@ -9,9 +9,9 @@ import cn.dev33.satoken.strategy.SaStrategy;
* @author noear
* @since 1.4
*/
-public class SaTokenMethodInterceptor implements Interceptor {
+public class SaTokenAnnotationInterceptor implements Interceptor {
- public static final SaTokenMethodInterceptor INSTANCE = new SaTokenMethodInterceptor();
+ public static final SaTokenAnnotationInterceptor INSTANCE = new SaTokenAnnotationInterceptor();
@Override
public Object doIntercept(Invocation inv) throws Throwable {
diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java
index 6014aca8..ef5e760e 100644
--- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java
+++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java
@@ -1,12 +1,12 @@
package cn.dev33.satoken.solon.integration;
-
import cn.dev33.satoken.exception.BackResultException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
import cn.dev33.satoken.router.SaRouter;
+import org.noear.solon.Utils;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
@@ -16,24 +16,26 @@ import java.util.Arrays;
import java.util.List;
/**
- * @author noear 2021/5/30 created
+ * @author noear
+ * @since 1.9
*/
public class SaTokenPathFilter implements Filter {
-
+
// ------------------------ 设置此过滤器 拦截 & 放行 的路由
/**
* 拦截路由
*/
- private List includeList = new ArrayList<>();
+ protected List includeList = new ArrayList<>();
/**
* 放行路由
*/
- private List excludeList = new ArrayList<>();
+ protected List excludeList = new ArrayList<>();
/**
* 添加 [拦截路由]
+ *
* @param paths 路由
* @return 对象自身
*/
@@ -44,6 +46,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 添加 [放行路由]
+ *
* @param paths 路由
* @return 对象自身
*/
@@ -54,6 +57,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 写入 [拦截路由] 集合
+ *
* @param pathList 路由集合
* @return 对象自身
*/
@@ -64,6 +68,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 写入 [放行路由] 集合
+ *
* @param pathList 路由集合
* @return 对象自身
*/
@@ -74,6 +79,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 获取 [拦截路由] 集合
+ *
* @return see note
*/
public List getIncludeList() {
@@ -82,6 +88,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 获取 [放行路由] 集合
+ *
* @return see note
*/
public List getExcludeList() {
@@ -94,22 +101,29 @@ public class SaTokenPathFilter implements Filter {
/**
* 认证函数:每次请求执行
*/
- public SaFilterAuthStrategy auth = r -> {};
+ protected SaFilterAuthStrategy auth = r -> {
+ };
/**
* 异常处理函数:每次[认证函数]发生异常时执行此函数
*/
- public SaFilterErrorStrategy error = e -> {
- throw new SaTokenException(e);
+ protected SaFilterErrorStrategy error = e -> {
+ if (e instanceof SaTokenException) {
+ throw (SaTokenException) e;
+ } else {
+ throw new SaTokenException(e);
+ }
};
/**
* 前置函数:在每次[认证函数]之前执行
*/
- public SaFilterAuthStrategy beforeAuth = r -> {};
+ protected SaFilterAuthStrategy beforeAuth = r -> {
+ };
/**
* 写入[认证函数]: 每次请求执行
+ *
* @param auth see note
* @return 对象自身
*/
@@ -120,6 +134,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数
+ *
* @param error see note
* @return 对象自身
*/
@@ -130,6 +145,7 @@ public class SaTokenPathFilter implements Filter {
/**
* 写入[前置函数]:在每次[认证函数]之前执行
+ *
* @param beforeAuth see note
* @return 对象自身
*/
@@ -144,23 +160,33 @@ public class SaTokenPathFilter implements Filter {
try {
// 执行全局过滤器
SaRouter.match(includeList).notMatch(excludeList).check(r -> {
- beforeAuth.run(null);
+ beforeAuth.run(null);
auth.run(null);
});
-
+
} catch (StopMatchException e) {
-
- } catch (Throwable e) {
- // 1. 获取异常处理策略结果
- String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e));
+
+ } catch (SaTokenException e) {
+ // 1. 获取异常处理策略结果
+ Object result;
+ if (e instanceof BackResultException) {
+ result = e.getMessage();
+ } else {
+ result = error.run(e);
+ }
// 2. 写入输出流
- ctx.contentType("text/plain; charset=utf-8");
- ctx.output(result);
+ if(result != null) {
+ ctx.render(result);
+ }
+ ctx.setHandled(true);
return;
+ } catch (Throwable e) {
+ // 异常解包
+ throw Utils.throwableUnwrap(e); //solon 的最后层还有保底处理
}
// 执行
chain.doFilter(ctx);
}
-}
+}
\ No newline at end of file
diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java
new file mode 100644
index 00000000..b89adca0
--- /dev/null
+++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java
@@ -0,0 +1,183 @@
+package cn.dev33.satoken.solon.integration;
+
+import cn.dev33.satoken.exception.BackResultException;
+import cn.dev33.satoken.exception.SaTokenException;
+import cn.dev33.satoken.exception.StopMatchException;
+import cn.dev33.satoken.filter.SaFilterAuthStrategy;
+import cn.dev33.satoken.filter.SaFilterErrorStrategy;
+import cn.dev33.satoken.router.SaRouter;
+import org.noear.solon.core.handle.Context;
+import org.noear.solon.core.handle.Handler;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * sa-token基于路由的拦截式鉴权
+ * @author kong
+ */
+public class SaTokenPathInterceptor implements Handler {
+
+ // ------------------------ 设置此过滤器 拦截 & 放行 的路由
+
+ /**
+ * 拦截路由
+ */
+ protected List includeList = new ArrayList<>();
+
+ /**
+ * 放行路由
+ */
+ protected List excludeList = new ArrayList<>();
+
+ /**
+ * 添加 [拦截路由]
+ *
+ * @param paths 路由
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor addInclude(String... paths) {
+ includeList.addAll(Arrays.asList(paths));
+ return this;
+ }
+
+ /**
+ * 添加 [放行路由]
+ *
+ * @param paths 路由
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor addExclude(String... paths) {
+ excludeList.addAll(Arrays.asList(paths));
+ return this;
+ }
+
+ /**
+ * 写入 [拦截路由] 集合
+ *
+ * @param pathList 路由集合
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor setIncludeList(List pathList) {
+ includeList = pathList;
+ return this;
+ }
+
+ /**
+ * 写入 [放行路由] 集合
+ *
+ * @param pathList 路由集合
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor setExcludeList(List pathList) {
+ excludeList = pathList;
+ return this;
+ }
+
+ /**
+ * 获取 [拦截路由] 集合
+ *
+ * @return see note
+ */
+ public List getIncludeList() {
+ return includeList;
+ }
+
+ /**
+ * 获取 [放行路由] 集合
+ *
+ * @return see note
+ */
+ public List getExcludeList() {
+ return excludeList;
+ }
+
+
+ // ------------------------ 钩子函数
+
+ /**
+ * 认证函数:每次请求执行
+ */
+ protected SaFilterAuthStrategy auth = r -> {
+ };
+
+ /**
+ * 异常处理函数:每次[认证函数]发生异常时执行此函数
+ */
+ protected SaFilterErrorStrategy error = e -> {
+ if (e instanceof SaTokenException) {
+ throw (SaTokenException) e;
+ } else {
+ throw new SaTokenException(e);
+ }
+ };
+
+ /**
+ * 前置函数:在每次[认证函数]之前执行
+ */
+ protected SaFilterAuthStrategy beforeAuth = r -> {
+ };
+
+ /**
+ * 写入[认证函数]: 每次请求执行
+ *
+ * @param auth see note
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor setAuth(SaFilterAuthStrategy auth) {
+ this.auth = auth;
+ return this;
+ }
+
+ /**
+ * 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数
+ *
+ * @param error see note
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor setError(SaFilterErrorStrategy error) {
+ this.error = error;
+ return this;
+ }
+
+ /**
+ * 写入[前置函数]:在每次[认证函数]之前执行
+ *
+ * @param beforeAuth see note
+ * @return 对象自身
+ */
+ public SaTokenPathInterceptor setBeforeAuth(SaFilterAuthStrategy beforeAuth) {
+ this.beforeAuth = beforeAuth;
+ return this;
+ }
+
+
+ @Override
+ public void handle(Context ctx) throws Throwable {
+ try {
+ // 执行全局过滤器
+ SaRouter.match(includeList).notMatch(excludeList).check(r -> {
+ beforeAuth.run(null);
+ auth.run(null);
+ });
+
+ } catch (StopMatchException e) {
+
+ } catch (SaTokenException e) {
+ // 1. 获取异常处理策略结果
+ Object result;
+ if (e instanceof BackResultException) {
+ result = e.getMessage();
+ } else {
+ result = error.run(e);
+ }
+
+ // 2. 写入输出流
+ if(result != null) {
+ ctx.render(result);
+ }
+ ctx.setHandled(true);
+ }
+ }
+}
diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaContextForSolon.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaContextForSolon.java
similarity index 96%
rename from sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaContextForSolon.java
rename to sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaContextForSolon.java
index e372aa01..e6ef1cc6 100644
--- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaContextForSolon.java
+++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaContextForSolon.java
@@ -1,4 +1,4 @@
-package cn.dev33.satoken.solon.integration;
+package cn.dev33.satoken.solon.model;
import cn.dev33.satoken.context.SaTokenContext;
import cn.dev33.satoken.context.model.SaRequest;
diff --git a/sa-token-starter/sa-token-solon-plugin/src/test/java/demo/App.java b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo/App.java
new file mode 100644
index 00000000..ac68f579
--- /dev/null
+++ b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo/App.java
@@ -0,0 +1,12 @@
+package demo;
+
+import org.noear.solon.Solon;
+
+/**
+ * @author noear 2022/3/30 created
+ */
+public class App {
+ public static void main(String[] args) {
+ Solon.start(App.class, args);
+ }
+}
diff --git a/sa-token-starter/sa-token-solon-plugin/src/test/java/demo/Config.java b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo/Config.java
new file mode 100644
index 00000000..8bd221b1
--- /dev/null
+++ b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo/Config.java
@@ -0,0 +1,41 @@
+package demo;
+
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.solon.integration.SaTokenPathFilter;
+import cn.dev33.satoken.stp.StpUtil;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.core.handle.Filter;
+
+/**
+ * @author noear 2022/3/30 created
+ */
+@Configuration
+public class Config {
+
+ @Bean
+ public Filter saTokenFilter() {
+ return new SaTokenPathFilter()
+ // 指定 [拦截路由] 与 [放行路由]
+ .addInclude("/**").addExclude("/favicon.ico")
+
+ // 认证函数: 每次请求执行
+ .setAuth(s -> {
+ SaRouter.match("/**", StpUtil::checkLogin);
+
+ // 根据路由划分模块,不同模块不同鉴权
+ SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
+ SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
+ SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
+ SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
+ })
+
+ // 异常处理函数:每次认证函数发生异常时执行此函数
+ .setError(e -> {
+ System.out.println("---------- sa全局异常 ");
+ System.out.println(e.getMessage());
+ StpUtil.login(123);
+ return e.getMessage();
+ });
+ }
+}
diff --git a/sa-token-starter/sa-token-solon-plugin/src/test/java/demo2/App.java b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo2/App.java
new file mode 100644
index 00000000..8b9ff8b5
--- /dev/null
+++ b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo2/App.java
@@ -0,0 +1,12 @@
+package demo2;
+
+import org.noear.solon.Solon;
+
+/**
+ * @author noear 2022/3/30 created
+ */
+public class App {
+ public static void main(String[] args) {
+ Solon.start(App.class, args);
+ }
+}
diff --git a/sa-token-starter/sa-token-solon-plugin/src/test/java/demo2/Config.java b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo2/Config.java
new file mode 100644
index 00000000..7b970b72
--- /dev/null
+++ b/sa-token-starter/sa-token-solon-plugin/src/test/java/demo2/Config.java
@@ -0,0 +1,53 @@
+package demo2;
+
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.solon.integration.SaTokenPathInterceptor;
+import cn.dev33.satoken.stp.StpUtil;
+import org.noear.solon.Solon;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Configuration;
+
+/**
+ * @author noear 2022/7/11 created
+ */
+@Configuration
+public class Config {
+ @Bean
+ public void saTokenPathInterceptor() {
+ Solon.app().before(new SaTokenPathInterceptor()
+ // 指定 [拦截路由] 与 [放行路由]
+ .addInclude("/**").addExclude("/favicon.ico")
+
+ // 认证函数: 每次请求执行
+ .setAuth(s -> {
+ SaRouter.match("/**", StpUtil::checkLogin);
+
+ // 根据路由划分模块,不同模块不同鉴权
+ SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
+ SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
+ SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
+ SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
+ })
+
+ // 异常处理函数:每次认证函数发生异常时执行此函数
+ .setError(e -> {
+ System.out.println("---------- sa全局异常 ");
+ System.out.println(e.getMessage());
+ StpUtil.login(123);
+ return e.getMessage();
+ })
+ );
+ }
+
+ @Bean
+ public void saTokenPathInterceptor2() {
+ Solon.app().before((ctx) -> {
+ SaRouter.match("/**", StpUtil::checkLogin);
+ // 根据路由划分模块,不同模块不同鉴权
+ SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
+ SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
+ SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
+ SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
+ });
+ }
+}
diff --git a/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml b/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml
new file mode 100644
index 00000000..5dd15890
--- /dev/null
+++ b/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml
@@ -0,0 +1,26 @@
+
+
+# sa-token配置
+sa-token:
+ # token名称 (同时也是cookie名称)
+ token-name: satoken
+ # token有效期,单位s 默认30天, -1代表永不过期
+ timeout: 2592000
+ # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
+ activity-timeout: -1
+ # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
+ allow-concurrent-login: true
+ # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
+ is-share: true
+ # token风格
+ token-style: uuid
+ # 是否输出操作日志
+ is-log: false
+
+
+sa-token-dao: #名字可以随意取
+ redis:
+ server: "localhost:6379"
+ password: 123456
+ db: 1
+ maxTotal: 200