mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-10-21 02:57:23 +08:00
添加solon适配及demo
This commit is contained in:
32
sa-token-starter/sa-token-solon-plugin/pom.xml
Normal file
32
sa-token-starter/sa-token-solon-plugin/pom.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-starter</artifactId>
|
||||
<version>1.19.0</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-solon-plugin</name>
|
||||
<artifactId>sa-token-solon-plugin</artifactId>
|
||||
<description>solon integrate sa-token</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.noear</groupId>
|
||||
<artifactId>solon</artifactId>
|
||||
<version>1.4.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>1.19.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
@@ -0,0 +1,60 @@
|
||||
package cn.dev33.satoken.solon;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.listener.SaTokenListener;
|
||||
import cn.dev33.satoken.solon.integration.SaTokenMethodInterceptor;
|
||||
import cn.dev33.satoken.solon.integration.SaContextForSolon;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.SolonApp;
|
||||
import org.noear.solon.core.Aop;
|
||||
import org.noear.solon.core.Plugin;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.4
|
||||
*/
|
||||
public class XPluginImp implements Plugin {
|
||||
@Override
|
||||
public void start(SolonApp app) {
|
||||
Aop.context().beanAroundAdd(SaCheckPermission.class, SaTokenMethodInterceptor.instance);
|
||||
Aop.context().beanAroundAdd(SaCheckRole.class, SaTokenMethodInterceptor.instance);
|
||||
Aop.context().beanAroundAdd(SaCheckLogin.class, SaTokenMethodInterceptor.instance);
|
||||
|
||||
//集成初始化
|
||||
|
||||
//注入配置Bean
|
||||
SaTokenConfig saTokenConfig = Solon.cfg().getBean("solon.sa-token", SaTokenConfig.class);
|
||||
SaManager.setConfig(saTokenConfig);
|
||||
|
||||
|
||||
//注入容器交互Bean
|
||||
SaManager.setSaTokenContext(new SaContextForSolon());
|
||||
|
||||
//注入侦听器Bean
|
||||
Aop.getAsyn(SaTokenListener.class, bw->{
|
||||
SaManager.setSaTokenListener(bw.raw());
|
||||
});
|
||||
|
||||
//注入框架行为Bean
|
||||
Aop.getAsyn(SaTokenAction.class, bw->{
|
||||
SaManager.setSaTokenAction(bw.raw());
|
||||
});
|
||||
|
||||
//注入权限认证Bean
|
||||
Aop.getAsyn(StpInterface.class, bw->{
|
||||
SaManager.setStpInterface(bw.raw());
|
||||
});
|
||||
|
||||
//注入持久化Bean
|
||||
Aop.getAsyn(SaTokenDao.class, bw->{
|
||||
SaManager.setSaTokenDao(bw.raw());
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package cn.dev33.satoken.solon.integration;
|
||||
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.solon.model.SaRequestForSolon;
|
||||
import cn.dev33.satoken.solon.model.SaResponseForSolon;
|
||||
import cn.dev33.satoken.solon.model.SaStorageForSolon;
|
||||
import org.noear.solon.core.util.PathAnalyzer;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.4
|
||||
*/
|
||||
public class SaContextForSolon implements SaTokenContext {
|
||||
/**
|
||||
* 获取当前请求的Request对象
|
||||
*/
|
||||
@Override
|
||||
public SaRequest getRequest() {
|
||||
return new SaRequestForSolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的Response对象
|
||||
*/
|
||||
@Override
|
||||
public SaResponse getResponse() {
|
||||
return new SaResponseForSolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 [存储器] 对象
|
||||
*/
|
||||
@Override
|
||||
public SaStorage getStorage() {
|
||||
return new SaStorageForSolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验指定路由匹配符是否可以匹配成功指定路径
|
||||
*/
|
||||
@Override
|
||||
public boolean matchPath(String pattern, String path) {
|
||||
return PathAnalyzer.get(path).matches(path);
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package cn.dev33.satoken.solon.integration;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import org.noear.solon.core.aspect.Interceptor;
|
||||
import org.noear.solon.core.aspect.Invocation;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.4
|
||||
*/
|
||||
public class SaTokenMethodInterceptor implements Interceptor {
|
||||
public static final SaTokenMethodInterceptor instance = new SaTokenMethodInterceptor();
|
||||
|
||||
@Override
|
||||
public Object doIntercept(Invocation inv) throws Throwable {
|
||||
// 注解鉴权
|
||||
SaManager.getSaTokenAction().checkMethodAnnotation(inv.method().getMethod());
|
||||
|
||||
// 执行原有逻辑
|
||||
return inv.invoke();
|
||||
}
|
||||
}
|
@@ -0,0 +1,162 @@
|
||||
package cn.dev33.satoken.solon.integration;
|
||||
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
|
||||
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
|
||||
import cn.dev33.satoken.router.SaRouterUtil;
|
||||
import org.noear.solon.core.handle.Context;
|
||||
import org.noear.solon.core.handle.Filter;
|
||||
import org.noear.solon.core.handle.FilterChain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author noear 2021/5/30 created
|
||||
*/
|
||||
public class SaTokenPathFilter implements Filter {
|
||||
// ------------------------ 设置此过滤器 拦截 & 放行 的路由
|
||||
|
||||
/**
|
||||
* 拦截路由
|
||||
*/
|
||||
private List<String> includeList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 放行路由
|
||||
*/
|
||||
private List<String> excludeList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 添加 [拦截路由]
|
||||
* @param paths 路由
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter addInclude(String... paths) {
|
||||
includeList.addAll(Arrays.asList(paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 [放行路由]
|
||||
* @param paths 路由
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter addExclude(String... paths) {
|
||||
excludeList.addAll(Arrays.asList(paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 [拦截路由] 集合
|
||||
* @param pathList 路由集合
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter setIncludeList(List<String> pathList) {
|
||||
includeList = pathList;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 [放行路由] 集合
|
||||
* @param pathList 路由集合
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter setExcludeList(List<String> pathList) {
|
||||
excludeList = pathList;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [拦截路由] 集合
|
||||
* @return see note
|
||||
*/
|
||||
public List<String> getIncludeList() {
|
||||
return includeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [放行路由] 集合
|
||||
* @return see note
|
||||
*/
|
||||
public List<String> getExcludeList() {
|
||||
return excludeList;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ 钩子函数
|
||||
|
||||
/**
|
||||
* 认证函数:每次请求执行
|
||||
*/
|
||||
public SaFilterAuthStrategy auth = r -> {};
|
||||
|
||||
/**
|
||||
* 异常处理函数:每次[认证函数]发生异常时执行此函数
|
||||
*/
|
||||
public SaFilterErrorStrategy error = e -> {
|
||||
throw new SaTokenException(e);
|
||||
};
|
||||
|
||||
/**
|
||||
* 前置函数:在每次[认证函数]之前执行
|
||||
*/
|
||||
public SaFilterAuthStrategy beforeAuth = r -> {};
|
||||
|
||||
/**
|
||||
* 写入[认证函数]: 每次请求执行
|
||||
* @param auth see note
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter setAuth(SaFilterAuthStrategy auth) {
|
||||
this.auth = auth;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数
|
||||
* @param error see note
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter setError(SaFilterErrorStrategy error) {
|
||||
this.error = error;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入[前置函数]:在每次[认证函数]之前执行
|
||||
* @param beforeAuth see note
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenPathFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) {
|
||||
this.beforeAuth = beforeAuth;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
|
||||
try {
|
||||
// 执行全局过滤器
|
||||
SaRouterUtil.match(includeList, excludeList, () -> {
|
||||
beforeAuth.run(null);
|
||||
auth.run(null);
|
||||
});
|
||||
|
||||
} catch (Throwable e) {
|
||||
// 1. 获取异常处理策略结果
|
||||
Object result = error.run(e);
|
||||
String resultString = String.valueOf(result);
|
||||
|
||||
// 2. 写入输出流
|
||||
ctx.contentType("text/plain; charset=utf-8");
|
||||
ctx.output(resultString);
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行
|
||||
chain.doFilter(ctx);
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package cn.dev33.satoken.solon.model;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import org.noear.solon.core.handle.Context;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.4
|
||||
*/
|
||||
public class SaRequestForSolon implements SaRequest {
|
||||
Context ctx;
|
||||
public SaRequestForSolon(){
|
||||
ctx = Context.current();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String s) {
|
||||
return ctx.param(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String s) {
|
||||
return ctx.header(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCookieValue(String s) {
|
||||
return ctx.cookie(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestPath() {
|
||||
return ctx.pathNew();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return ctx.method();
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package cn.dev33.satoken.solon.model;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import org.noear.solon.Utils;
|
||||
import org.noear.solon.core.handle.Context;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.4
|
||||
*/
|
||||
public class SaResponseForSolon implements SaResponse {
|
||||
Context ctx;
|
||||
|
||||
public SaResponseForSolon() {
|
||||
ctx = Context.current();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCookie(String s) {
|
||||
ctx.cookieRemove(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCookie(String name, String value, String path, String domain, int timeout) {
|
||||
if (Utils.isNotEmpty(path)) {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
ctx.cookieSet(name, value, domain, path, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaResponse setHeader(String name, String value) {
|
||||
ctx.headerSet(name, value);
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package cn.dev33.satoken.solon.model;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import org.noear.solon.core.handle.Context;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.4
|
||||
*/
|
||||
public class SaStorageForSolon implements SaStorage {
|
||||
Context ctx;
|
||||
|
||||
public SaStorageForSolon() {
|
||||
ctx = Context.current();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String key, Object value) {
|
||||
ctx.attrSet(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
return ctx.attr(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String key) {
|
||||
ctx.attrMap().remove(key);
|
||||
}
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* sa-token集成SpringBoot的各个组件
|
||||
*/
|
||||
package cn.dev33.satoken.solon;
|
@@ -0,0 +1 @@
|
||||
solon.plugin=cn.dev33.satoken.solon.XPluginImp
|
Reference in New Issue
Block a user