mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
Compare commits
4 Commits
9b7efbbcc8
...
e8fe3a83c7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8fe3a83c7 | ||
|
|
8c0177c598 | ||
|
|
fc27e2a49d | ||
|
|
7c95ec51fa |
9
pom.xml
9
pom.xml
@@ -19,6 +19,9 @@
|
||||
<!-- 所有模块 -->
|
||||
<modules>
|
||||
<module>sa-token-dependencies</module>
|
||||
<module>sa-token-spring-boot2-dependencies</module>
|
||||
<module>sa-token-spring-boot3-dependencies</module>
|
||||
<module>sa-token-spring-boot4-dependencies</module>
|
||||
<module>sa-token-bom</module>
|
||||
<module>sa-token-core</module>
|
||||
<module>sa-token-starter</module>
|
||||
@@ -75,7 +78,11 @@
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!--
|
||||
导入 sa-token-dependencies 所有版本定义,并传导到每个子项目。
|
||||
需要注意的是:该 import 只会导入 <dependencyManagement> 部分,而不会导入 <dependencies> 部分和 <properties> 部分。
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dependencies</artifactId>
|
||||
|
||||
@@ -51,6 +51,11 @@
|
||||
<artifactId>sa-token-reactor-spring-boot3-starter</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-reactor-spring-boot4-starter</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-servlet</artifactId>
|
||||
@@ -68,7 +73,12 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-v3v4-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
<module>sa-token-demo-thymeleaf</module>
|
||||
<module>sa-token-demo-webflux</module>
|
||||
<module>sa-token-demo-webflux-springboot3</module>
|
||||
<module>sa-token-demo-webflux-springboot4</module>
|
||||
<module>sa-token-demo-websocket</module>
|
||||
<module>sa-token-demo-websocket-spring</module>
|
||||
<module>sa-token-demo-loveqq-boot</module>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aspectj</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:https://sa-token.cc/ -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
@@ -38,10 +38,10 @@
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||
<!-- Sa-Token整合 Redis -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
61
sa-token-demo/sa-token-demo-webflux-springboot4/pom.xml
Normal file
61
sa-token-demo/sa-token-demo-webflux-springboot4/pom.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<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>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-demo-webflux-springboot4</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<!-- SpringBoot 4 -->
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>4.0.3</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<!-- 定义 Sa-Token 版本号 -->
|
||||
<properties>
|
||||
<sa-token.version>1.44.0</sa-token.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- springboot依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 权限认证(Reactor响应式集成), 在线文档:https://sa-token.cc/ -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-reactor-spring-boot4-starter</artifactId>
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 整合 Redis -->
|
||||
<!-- <dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency> -->
|
||||
|
||||
<!-- 提供redis连接池 -->
|
||||
<!-- <dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency> -->
|
||||
|
||||
<!-- @ConfigurationProperties -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.pj;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* Sa-Token整合webflux 示例 (springboot4)
|
||||
*
|
||||
* @author click33
|
||||
* @since 2023年1月3日
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class SaTokenWebfluxSpringboot4Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenWebfluxSpringboot4Application.class, args);
|
||||
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.pj.satoken;
|
||||
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 自定义过滤器
|
||||
*/
|
||||
@Component
|
||||
public class MyFilter implements WebFilter {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
System.out.println("进入自定义过滤器");
|
||||
|
||||
try {
|
||||
// 先 set 上下文,再调用 Sa-Token 同步 API,并在 finally 里清除上下文
|
||||
SaReactorSyncHolder.setContext(exchange);
|
||||
System.out.println(StpUtil.isLogin());
|
||||
}
|
||||
finally {
|
||||
SaReactorSyncHolder.clearContext();
|
||||
}
|
||||
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.pj.satoken;
|
||||
|
||||
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* [Sa-Token 权限认证] 配置类
|
||||
* @author click33
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class SaTokenConfigure {
|
||||
|
||||
/**
|
||||
* 注册 [sa-token全局过滤器]
|
||||
*/
|
||||
@Bean
|
||||
public SaReactorFilter getSaReactorFilter() {
|
||||
return new SaReactorFilter()
|
||||
// 指定 [拦截路由]
|
||||
.addInclude("/**")
|
||||
// 指定 [放行路由]
|
||||
.addExclude("/favicon.ico")
|
||||
// 指定[认证函数]: 每次请求执行
|
||||
.setAuth(r -> {
|
||||
System.out.println("---------- sa全局认证");
|
||||
// SaRouter.match("/test/test", () -> StpUtil.checkLogin());
|
||||
})
|
||||
// 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数
|
||||
.setError(e -> {
|
||||
System.out.println("---------- sa全局异常 ");
|
||||
return SaResult.error(e.getMessage());
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.pj.satoken;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
|
||||
/**
|
||||
* 自定义权限验证接口扩展
|
||||
*/
|
||||
@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
|
||||
public class StpInterfaceImpl implements StpInterface {
|
||||
|
||||
/**
|
||||
* 返回一个账号所拥有的权限码集合
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("101");
|
||||
list.add("user-add");
|
||||
list.add("user-delete");
|
||||
list.add("user-update");
|
||||
list.add("user-get");
|
||||
list.add("article-get");
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回一个账号所拥有的角色标识集合
|
||||
*/
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("admin");
|
||||
list.add("super-admin");
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.pj.test;
|
||||
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class DefineRoutes {
|
||||
|
||||
/**
|
||||
* 函数式编程,初始化路由表
|
||||
* @return 路由表
|
||||
*/
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> getRoutes() {
|
||||
return RouterFunctions.route(RequestPredicates.GET("/fun"), req -> {
|
||||
return SaReactorSyncHolder.setContext(req.exchange(), () -> {
|
||||
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||
SaResult res = SaResult.data(StpUtil.getTokenInfo());
|
||||
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(res);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.pj.test;
|
||||
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/**
|
||||
* 全局异常处理
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class GlobalException {
|
||||
|
||||
@ExceptionHandler
|
||||
public SaResult handlerException(Exception e) {
|
||||
e.printStackTrace();
|
||||
return SaResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.pj.test;
|
||||
|
||||
import cn.dev33.satoken.reactor.context.SaReactorHolder;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* 测试专用Controller
|
||||
* @author click33
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/test/")
|
||||
public class TestController {
|
||||
|
||||
@Autowired
|
||||
UserService userService;
|
||||
|
||||
// 登录测试:Controller 里调用 Sa-Token API --- http://localhost:8081/test/login
|
||||
@RequestMapping("login")
|
||||
public Mono<SaResult> login(@RequestParam(defaultValue="10001") String id) {
|
||||
return SaReactorHolder.sync(() -> {
|
||||
StpUtil.login(id);
|
||||
return SaResult.ok("登录成功");
|
||||
});
|
||||
}
|
||||
|
||||
// API测试:手动设置上下文、try-finally 形式 --- http://localhost:8081/test/isLogin
|
||||
@RequestMapping("isLogin")
|
||||
public SaResult isLogin(ServerWebExchange exchange) {
|
||||
try {
|
||||
SaReactorSyncHolder.setContext(exchange);
|
||||
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
} finally {
|
||||
SaReactorSyncHolder.clearContext();
|
||||
}
|
||||
}
|
||||
|
||||
// API测试:手动设置上下文、lambda 表达式形式 --- http://localhost:8081/test/isLogin2
|
||||
@RequestMapping("isLogin2")
|
||||
public SaResult isLogin2(ServerWebExchange exchange) {
|
||||
SaResult res = SaReactorSyncHolder.setContext(exchange, ()->{
|
||||
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
});
|
||||
return SaResult.data(res);
|
||||
}
|
||||
|
||||
// API测试:自动设置上下文、lambda 表达式形式 --- http://localhost:8081/test/isLogin3
|
||||
@RequestMapping("isLogin3")
|
||||
public Mono<SaResult> isLogin3() {
|
||||
return SaReactorHolder.sync(() -> {
|
||||
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||
userService.isLogin();
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
});
|
||||
}
|
||||
|
||||
// API测试:自动设置上下文、调用 userService Mono 方法 --- http://localhost:8081/test/isLogin4
|
||||
@RequestMapping("isLogin4")
|
||||
public Mono<SaResult> isLogin4() {
|
||||
return userService.findUserIdByNamePwd("ZhangSan", "123456").flatMap(userId -> {
|
||||
return SaReactorHolder.sync(() -> {
|
||||
StpUtil.login(userId);
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// API测试:切换线程、复杂嵌套调用 --- http://localhost:8081/test/isLogin5
|
||||
@RequestMapping("isLogin5")
|
||||
public Mono<SaResult> isLogin5() {
|
||||
System.out.println("线程id-----" + Thread.currentThread().getId());
|
||||
// 要点:在流里调用 Sa-Token API 之前,必须用 SaReactorHolder.sync( () -> {} ) 进行包裹
|
||||
return Mono.delay(Duration.ofSeconds(1))
|
||||
.doOnNext(r-> System.out.println("线程id-----" + Thread.currentThread().getId()))
|
||||
.map(r-> SaReactorHolder.sync( () -> userService.isLogin() ))
|
||||
.map(r-> userService.findUserIdByNamePwd("ZhangSan", "123456"))
|
||||
.map(r-> SaReactorHolder.sync( () -> userService.isLogin() ))
|
||||
.flatMap(isLogin -> {
|
||||
System.out.println("是否登录 " + isLogin);
|
||||
return SaReactorHolder.sync(() -> {
|
||||
System.out.println("是否登录 " + StpUtil.isLogin());
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// API测试:使用上下文无关的API --- http://localhost:8081/test/isLogin6
|
||||
@RequestMapping("isLogin6")
|
||||
public SaResult isLogin6(@CookieValue("satoken") String satoken) {
|
||||
System.out.println("token 为:" + satoken);
|
||||
System.out.println("登录人:" + StpUtil.getLoginIdByToken(satoken));
|
||||
return SaResult.ok("登录人:" + StpUtil.getLoginIdByToken(satoken));
|
||||
}
|
||||
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||
@RequestMapping("test")
|
||||
public SaResult test() {
|
||||
System.out.println("线程id------- " + Thread.currentThread().getId());
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.pj.test;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 模拟 Service 方法
|
||||
* @author click33
|
||||
* @since 2025/4/6
|
||||
*/
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
public boolean isLogin() {
|
||||
System.out.println("UserService 里调用 API 测试,是否登录:" + StpUtil.isLogin());
|
||||
return StpUtil.isLogin();
|
||||
}
|
||||
|
||||
public Mono<Long> findUserIdByNamePwd(String name, String pwd) {
|
||||
// ...
|
||||
return Mono.just(10001L);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
# sa-token 配置
|
||||
sa-token:
|
||||
# token 名称 (同时也是 cookie 名称)
|
||||
token-name: satoken
|
||||
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
||||
timeout: 2592000
|
||||
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||
active-timeout: -1
|
||||
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
||||
is-concurrent: true
|
||||
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
|
||||
is-share: false
|
||||
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
|
||||
token-style: uuid
|
||||
# 是否输出操作日志
|
||||
is-log: true
|
||||
|
||||
spring:
|
||||
# redis配置
|
||||
redis:
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器地址
|
||||
host: 127.0.0.1
|
||||
# Redis服务器连接端口
|
||||
port: 6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password:
|
||||
# 连接超时时间(毫秒)
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 200
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 10
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
<revision>1.44.0</revision>
|
||||
|
||||
<!-- 统一定义依赖版本号 -->
|
||||
<springboot.version>2.7.18</springboot.version>
|
||||
<!-- <springboot.version>2.7.18</springboot.version>-->
|
||||
<springboot3.version>3.4.3</springboot3.version>
|
||||
<springboot4.version>4.0.3</springboot4.version>
|
||||
<spring-web.low.version>5.3.39</spring-web.low.version>
|
||||
<!-- <spring-web.low.version>5.3.39</spring-web.low.version>-->
|
||||
<reactor-core.version>3.7.4</reactor-core.version>
|
||||
<jackson-databind.version>2.13.4.1</jackson-databind.version>
|
||||
<jackson-datatype-jsr310.version>2.11.2</jackson-datatype-jsr310.version>
|
||||
@@ -65,34 +65,13 @@
|
||||
<version>${jakarta-servlet-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-webmvc (Spring Boot 4) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webmvc</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-web -->
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>5.3.7</version>
|
||||
</dependency> -->
|
||||
|
||||
|
||||
<!-- reactor-core -->
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
@@ -100,14 +79,14 @@
|
||||
<version>${reactor-core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-databind -->
|
||||
<!-- jackson2 databind -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-databind.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-databind 3.x (tools.jackson) -->
|
||||
<!-- jackson3 databind (tools.jackson) -->
|
||||
<dependency>
|
||||
<groupId>tools.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
@@ -163,25 +142,7 @@
|
||||
<version>${loveqq.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency> -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ****************** sa-token-plugin 相关依赖 ****************** -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Redisson 相关操作API -->
|
||||
<dependency>
|
||||
@@ -252,26 +213,6 @@
|
||||
<version>${freemarker.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-thymeleaf -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-aop -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool-jwt -->
|
||||
<dependency>
|
||||
|
||||
@@ -56,10 +56,28 @@
|
||||
|
||||
<dependencies>
|
||||
<!-- spring-boot-configuration -->
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>2.5.14</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- 默认使用 sa-token springboot2 相关依赖版本定义,子模块也可以引入其它的进行覆盖 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot2-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -32,6 +32,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>2.5.14</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
95
sa-token-spring-boot2-dependencies/pom.xml
Normal file
95
sa-token-spring-boot2-dependencies/pom.xml
Normal file
@@ -0,0 +1,95 @@
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!-- 父仓库 -->
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>sa-token-spring-boot2-dependencies</artifactId>
|
||||
<name>sa-token-spring-boot2-dependencies</name>
|
||||
<description>Sa-Token SpringBoot2 Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<springboot.version>2.7.18</springboot.version>
|
||||
<spring-web.low.version>5.3.39</spring-web.low.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-configuration-processor -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-web.low.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring-web.low.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- ****************** sa-token-plugin 相关依赖 ****************** -->
|
||||
|
||||
<!-- spring-boot-starter-data-redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-thymeleaf -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-aop -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
49
sa-token-spring-boot3-dependencies/pom.xml
Normal file
49
sa-token-spring-boot3-dependencies/pom.xml
Normal file
@@ -0,0 +1,49 @@
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!-- 父仓库 -->
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>sa-token-spring-boot3-dependencies</artifactId>
|
||||
<name>sa-token-spring-boot3-dependencies</name>
|
||||
<description>Sa-Token SpringBoot3 Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<springboot3.version>3.0.1</springboot3.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${springboot3.version}</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-starter-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${springboot3.version}</version>
|
||||
</dependency>
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot3.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
61
sa-token-spring-boot4-dependencies/pom.xml
Normal file
61
sa-token-spring-boot4-dependencies/pom.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!-- 父仓库 -->
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>sa-token-spring-boot4-dependencies</artifactId>
|
||||
<name>sa-token-spring-boot4-dependencies</name>
|
||||
<description>Sa-Token SpringBoot4 Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<springboot4.version>4.0.3</springboot4.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-starter-webmvc -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webmvc</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
<!-- spring-web (for reactor/webflux) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>7.0.3</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-starter-webflux (for reactor) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -20,12 +20,14 @@
|
||||
<modules>
|
||||
<module>sa-token-servlet</module>
|
||||
<module>sa-token-jakarta-servlet</module>
|
||||
<module>sa-token-spring-boot-autoconfig</module>
|
||||
<module>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</module>
|
||||
<module>sa-token-spring-boot-starter</module>
|
||||
<module>sa-token-spring-boot-webmvc-v3v4-common</module>
|
||||
<module>sa-token-spring-boot3-starter</module>
|
||||
<module>sa-token-spring-boot4-starter</module>
|
||||
<module>sa-token-reactor-spring-boot-starter</module>
|
||||
<module>sa-token-reactor-spring-boot3-starter</module>
|
||||
<module>sa-token-reactor-spring-boot4-starter</module>
|
||||
<module>sa-token-solon-plugin</module>
|
||||
<module>sa-token-jboot-plugin</module>
|
||||
<module>sa-token-jfinal-plugin</module>
|
||||
|
||||
@@ -51,23 +51,32 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-autoconfig -->
|
||||
<!-- sa-token-spring-boot-webmvc-reactor-v2v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jackson: JSON serialization -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>5.3.39</version>
|
||||
</dependency>
|
||||
<!-- sa-token springboot2 相关依赖版本定义 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot2-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@@ -55,12 +55,18 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-autoconfig -->
|
||||
<!-- sa-token-spring-boot-webmvc-reactor-v2v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jackson: JSON serialization -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -79,13 +85,6 @@
|
||||
<version>6.2.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-databind (optional) -->
|
||||
<!--<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.14.1</version>
|
||||
</dependency>-->
|
||||
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-starter</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-reactor-spring-boot4-starter</name>
|
||||
<artifactId>sa-token-reactor-spring-boot4-starter</artifactId>
|
||||
<description>springboot4 reactor integrate sa-token</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring-boot-starter (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-web (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- reactor-core -->
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-databind (optional) -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- config -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-webmvc-reactor-v2v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jackson3: JSON serialization for Spring Boot 4 (Jackson 3) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson3</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- sa-token springboot4 相关依赖版本定义 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot4-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.context;
|
||||
|
||||
import cn.dev33.satoken.fun.SaRetGenericFunction;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.context.Context;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
/**
|
||||
* Reactor 上下文操作(异步),持有当前请求的 ServerWebExchange 全局引用
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.19.0
|
||||
*/
|
||||
public class SaReactorHolder {
|
||||
|
||||
/**
|
||||
* ServerWebExchange key
|
||||
*/
|
||||
public static final String EXCHANGE_KEY = "SA_REACTOR_EXCHANGE_KEY";
|
||||
|
||||
/**
|
||||
* WebFilterChain key
|
||||
*/
|
||||
public static final String CHAIN_KEY = "SA_REACTOR__CHAIN_KEY";
|
||||
|
||||
/**
|
||||
* 在流式上下文写入 ServerWebExchange
|
||||
* @param ctx 必填
|
||||
* @param exchange 必填
|
||||
* @param chain 非必填
|
||||
* @return /
|
||||
*/
|
||||
public static Context setContext(Context ctx, ServerWebExchange exchange, WebFilterChain chain) {
|
||||
return ctx
|
||||
.put(EXCHANGE_KEY, exchange)
|
||||
.put(CHAIN_KEY, chain);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在流式上下文获取 ServerWebExchange
|
||||
* @param ctx /
|
||||
* @return /
|
||||
*/
|
||||
public static ServerWebExchange getExchange(ContextView ctx) {
|
||||
return ctx.get(EXCHANGE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在流式上下文获取 WebFilterChain
|
||||
* @param ctx /
|
||||
* @return /
|
||||
*/
|
||||
public static WebFilterChain getChain(ContextView ctx) {
|
||||
return ctx.get(CHAIN_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Mono < ServerWebExchange >
|
||||
* @return /
|
||||
*/
|
||||
public static Mono<ServerWebExchange> getMonoExchange() {
|
||||
return Mono.deferContextual(ctx -> Mono.just(getExchange(ctx)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 exchange 写入到同步上下文中,并执行一段代码,执行完毕清除上下文
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static <R> Mono<R> sync(SaRetGenericFunction<R> fun) {
|
||||
return Mono.deferContextual(ctx -> {
|
||||
try {
|
||||
SaReactorSyncHolder.setContext(ctx.get(EXCHANGE_KEY));
|
||||
return Mono.just(fun.run());
|
||||
} finally {
|
||||
SaReactorSyncHolder.clearContext();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.context;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
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.context.model.SaTokenContextModelBox;
|
||||
import cn.dev33.satoken.fun.SaRetGenericFunction;
|
||||
import cn.dev33.satoken.reactor.model.SaRequestForReactor;
|
||||
import cn.dev33.satoken.reactor.model.SaResponseForReactor;
|
||||
import cn.dev33.satoken.reactor.model.SaStorageForReactor;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Reactor上下文操作(同步),持有当前请求的 ServerWebExchange 全局引用
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.19.0
|
||||
*/
|
||||
public class SaReactorSyncHolder {
|
||||
|
||||
/**
|
||||
* 在同步上下文写入 ServerWebExchange
|
||||
* @param exchange /
|
||||
*/
|
||||
public static void setContext(ServerWebExchange exchange) {
|
||||
SaRequest request = new SaRequestForReactor(exchange.getRequest());
|
||||
SaResponse response = new SaResponseForReactor(exchange.getResponse());
|
||||
SaStorage storage = new SaStorageForReactor(exchange);
|
||||
SaManager.getSaTokenContext().setContext(request, response, storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在同步上下文清除 ServerWebExchange
|
||||
*/
|
||||
public static void clearContext() {
|
||||
SaManager.getSaTokenContext().clearContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在同步上下文获取 ServerWebExchange
|
||||
* @return /
|
||||
*/
|
||||
public static ServerWebExchange getExchange() {
|
||||
SaTokenContextModelBox box = SaManager.getSaTokenContext().getModelBox();
|
||||
return (ServerWebExchange)box.getStorage().getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 exchange 写入到同步上下文中,并执行一段代码,执行完毕清除上下文
|
||||
* @param exchange /
|
||||
* @param fun /
|
||||
*/
|
||||
public static <R>R setContext(ServerWebExchange exchange, SaRetGenericFunction<R> fun) {
|
||||
try {
|
||||
setContext(exchange);
|
||||
return fun.run();
|
||||
} finally {
|
||||
clearContext();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,61 +13,62 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.filter;
|
||||
package cn.dev33.satoken.reactor.filter;
|
||||
|
||||
import cn.dev33.satoken.exception.BackResultException;
|
||||
import cn.dev33.satoken.exception.FirewallCheckException;
|
||||
import cn.dev33.satoken.exception.StopMatchException;
|
||||
import cn.dev33.satoken.servlet.model.SaRequestForServlet;
|
||||
import cn.dev33.satoken.servlet.model.SaResponseForServlet;
|
||||
import cn.dev33.satoken.servlet.util.SaJakartaServletOperateUtil;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.reactor.model.SaRequestForReactor;
|
||||
import cn.dev33.satoken.reactor.model.SaResponseForReactor;
|
||||
import cn.dev33.satoken.reactor.util.SaReactorOperateUtil;
|
||||
import cn.dev33.satoken.strategy.SaFirewallStrategy;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 防火墙校验过滤器 (基于 Jakarta-Servlet)
|
||||
* 防火墙校验过滤器 (Reactor版)
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.37.0
|
||||
*/
|
||||
@Order(SaTokenConsts.FIREWALL_CHECK_FILTER_ORDER)
|
||||
public class SaFirewallCheckFilterForJakartaServlet implements Filter {
|
||||
public class SaFirewallCheckFilterForReactor implements WebFilter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse res = (HttpServletResponse) response;
|
||||
SaRequestForServlet saRequest = new SaRequestForServlet(req);
|
||||
SaResponseForServlet saResponse = new SaResponseForServlet(res);
|
||||
SaRequestForReactor saRequest = new SaRequestForReactor(exchange.getRequest());
|
||||
SaResponseForReactor saResponse = new SaResponseForReactor(exchange.getResponse());
|
||||
|
||||
try {
|
||||
SaFirewallStrategy.instance.check.execute(saRequest, saResponse, null);
|
||||
SaReactorSyncHolder.setContext(exchange);
|
||||
SaFirewallStrategy.instance.check.execute(saRequest, saResponse, exchange);
|
||||
}
|
||||
catch (StopMatchException ignored) {}
|
||||
catch (BackResultException e) {
|
||||
SaJakartaServletOperateUtil.writeResult(response, e.getMessage());
|
||||
return;
|
||||
return SaReactorOperateUtil.writeResult(exchange, e.getMessage());
|
||||
}
|
||||
// FirewallCheckException 异常则交由异常处理策略处理
|
||||
catch (FirewallCheckException e) {
|
||||
if(SaFirewallStrategy.instance.checkFailHandle == null) {
|
||||
SaJakartaServletOperateUtil.writeResult(response, e.getMessage());
|
||||
return SaReactorOperateUtil.writeResult(exchange, e.getMessage());
|
||||
} else {
|
||||
SaFirewallStrategy.instance.checkFailHandle.run(e, saRequest, saResponse, null);
|
||||
return Mono.empty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
finally {
|
||||
SaReactorSyncHolder.clearContext();
|
||||
}
|
||||
// 更多异常则不处理,交由 Web 框架处理
|
||||
|
||||
// 向内执行
|
||||
chain.doFilter(request, response);
|
||||
// 向下执行
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -13,24 +13,30 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.filter;
|
||||
package cn.dev33.satoken.reactor.filter;
|
||||
|
||||
import cn.dev33.satoken.exception.BackResultException;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.exception.StopMatchException;
|
||||
import cn.dev33.satoken.filter.SaFilter;
|
||||
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
|
||||
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.reactor.util.SaReactorOperateUtil;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.servlet.util.SaJakartaServletOperateUtil;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import jakarta.servlet.*;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 全局鉴权过滤器 (基于 Jakarta-Servlet)
|
||||
* Reactor 全局鉴权过滤器
|
||||
* <p>
|
||||
* 默认优先级为 -100,尽量保证在其它过滤器之前执行
|
||||
* </p>
|
||||
@@ -39,7 +45,7 @@ import java.util.List;
|
||||
* @since 1.34.0
|
||||
*/
|
||||
@Order(SaTokenConsts.ASSEMBLY_ORDER)
|
||||
public class SaServletFilter implements SaFilter, Filter {
|
||||
public class SaReactorFilter implements SaFilter, WebFilter {
|
||||
|
||||
// ------------------------ 设置此过滤器 拦截 & 放行 的路由
|
||||
|
||||
@@ -54,25 +60,25 @@ public class SaServletFilter implements SaFilter, Filter {
|
||||
public List<String> excludeList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public SaServletFilter addInclude(String... paths) {
|
||||
public SaReactorFilter addInclude(String... paths) {
|
||||
includeList.addAll(Arrays.asList(paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaServletFilter addExclude(String... paths) {
|
||||
public SaReactorFilter addExclude(String... paths) {
|
||||
excludeList.addAll(Arrays.asList(paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaServletFilter setIncludeList(List<String> pathList) {
|
||||
public SaReactorFilter setIncludeList(List<String> pathList) {
|
||||
includeList = pathList;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaServletFilter setExcludeList(List<String> pathList) {
|
||||
public SaReactorFilter setExcludeList(List<String> pathList) {
|
||||
excludeList = pathList;
|
||||
return this;
|
||||
}
|
||||
@@ -99,48 +105,45 @@ public class SaServletFilter implements SaFilter, Filter {
|
||||
public SaFilterAuthStrategy beforeAuth = r -> {};
|
||||
|
||||
@Override
|
||||
public SaServletFilter setAuth(SaFilterAuthStrategy auth) {
|
||||
public SaReactorFilter setAuth(SaFilterAuthStrategy auth) {
|
||||
this.auth = auth;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaServletFilter setError(SaFilterErrorStrategy error) {
|
||||
public SaReactorFilter setError(SaFilterErrorStrategy error) {
|
||||
this.error = error;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaServletFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) {
|
||||
public SaReactorFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) {
|
||||
this.beforeAuth = beforeAuth;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ doFilter
|
||||
// ------------------------ filter
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
|
||||
// ---------- 全局认证处理
|
||||
try {
|
||||
// 执行全局过滤器
|
||||
SaReactorSyncHolder.setContext(exchange);
|
||||
beforeAuth.run(null);
|
||||
SaRouter.match(includeList).notMatch(excludeList).check(r -> {
|
||||
auth.run(null);
|
||||
});
|
||||
SaRouter.match(includeList).notMatch(excludeList).check(r -> auth.run(null));
|
||||
}
|
||||
catch (StopMatchException ignored) {}
|
||||
catch (BackResultException e) {
|
||||
SaJakartaServletOperateUtil.writeResult(response, e.getMessage());
|
||||
return;
|
||||
return SaReactorOperateUtil.writeResult(exchange, e.getMessage());
|
||||
}
|
||||
catch (Throwable e) {
|
||||
SaJakartaServletOperateUtil.writeResult(response, String.valueOf(error.run(e)));
|
||||
return;
|
||||
return SaReactorOperateUtil.writeResult(exchange, String.valueOf(error.run(e)));
|
||||
}
|
||||
|
||||
// 执行
|
||||
chain.doFilter(request, response);
|
||||
finally {
|
||||
SaReactorSyncHolder.clearContext();
|
||||
}
|
||||
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,34 +13,32 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.filter;
|
||||
package cn.dev33.satoken.reactor.filter;
|
||||
|
||||
import cn.dev33.satoken.servlet.util.SaTokenContextJakartaServletUtil;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorHolder;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* SaTokenContext 上下文初始化过滤器 (基于 Jakarta-Servlet)
|
||||
* SaTokenContext 上下文初始化过滤器 (基于 Reactor)
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.42.0
|
||||
*/
|
||||
@Order(SaTokenConsts.SA_TOKEN_CONTEXT_FILTER_ORDER)
|
||||
public class SaTokenContextFilterForJakartaServlet implements Filter {
|
||||
public class SaTokenContextFilterForReactor implements WebFilter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
try {
|
||||
SaTokenContextJakartaServletUtil.setContext((HttpServletRequest) request, (HttpServletResponse) response);
|
||||
chain.doFilter(request, response);
|
||||
} finally {
|
||||
SaTokenContextJakartaServletUtil.clearContext();
|
||||
}
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
return chain.filter(exchange)
|
||||
.contextWrite(ctx -> SaReactorHolder.setContext(ctx, exchange, chain))
|
||||
.doFinally(r -> {
|
||||
// 在流式上下文中保存的数据会随着流式操作的结束而销毁,所以此处无需手动清除数据
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,43 +13,48 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.filter;
|
||||
package cn.dev33.satoken.reactor.filter;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||
import cn.dev33.satoken.exception.BackResultException;
|
||||
import cn.dev33.satoken.exception.StopMatchException;
|
||||
import cn.dev33.satoken.servlet.util.SaJakartaServletOperateUtil;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.reactor.util.SaReactorOperateUtil;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import jakarta.servlet.*;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* CORS 跨域策略过滤器 (基于 Jakarta-Servlet)
|
||||
* CORS 跨域策略过滤器 (基于 Reactor)
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.42.0
|
||||
*/
|
||||
@Order(SaTokenConsts.CORS_FILTER_ORDER)
|
||||
public class SaTokenCorsFilterForJakartaServlet implements Filter {
|
||||
public class SaTokenCorsFilterForReactor implements WebFilter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
|
||||
try {
|
||||
SaReactorSyncHolder.setContext(exchange);
|
||||
SaTokenContextModelBox box = SaHolder.getContext().getModelBox();
|
||||
SaStrategy.instance.corsHandle.execute(box.getRequest(), box.getResponse(), box.getStorage());
|
||||
}
|
||||
catch (StopMatchException ignored) {}
|
||||
catch (BackResultException e) {
|
||||
SaJakartaServletOperateUtil.writeResult(response, e.getMessage());
|
||||
return;
|
||||
return SaReactorOperateUtil.writeResult(exchange, e.getMessage());
|
||||
}
|
||||
finally {
|
||||
SaReactorSyncHolder.clearContext();
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.model;
|
||||
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.application.ApplicationInfo;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorHolder;
|
||||
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 对 SaRequest 包装类的实现(Reactor 响应式编程版)
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
public class SaRequestForReactor implements SaRequest {
|
||||
|
||||
/**
|
||||
* 底层Request对象
|
||||
*/
|
||||
protected ServerHttpRequest request;
|
||||
|
||||
/**
|
||||
* 实例化
|
||||
* @param request request对象
|
||||
*/
|
||||
public SaRequestForReactor(ServerHttpRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取底层源对象
|
||||
*/
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [请求体] 里获取一个值
|
||||
*/
|
||||
@Override
|
||||
public String getParam(String name) {
|
||||
return request.getQueryParams().getFirst(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [请求体] 里提交的所有参数名称
|
||||
* @return 参数名称列表
|
||||
*/
|
||||
@Override
|
||||
public Collection<String> getParamNames(){
|
||||
return request.getQueryParams().keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [请求体] 里提交的所有参数
|
||||
* @return 参数列表
|
||||
*/
|
||||
@Override
|
||||
public Map<String, String> getParamMap(){
|
||||
return request.getQueryParams().toSingleValueMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [请求头] 里获取一个值
|
||||
*/
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
return request.getHeaders().getFirst(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [Cookie作用域] 里获取一个值
|
||||
*/
|
||||
@Override
|
||||
public String getCookieValue(String name) {
|
||||
return getCookieLastValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [ Cookie作用域 ] 里获取一个值 (第一个此名称的)
|
||||
*/
|
||||
@Override
|
||||
public String getCookieFirstValue(String name){
|
||||
HttpCookie cookie = request.getCookies().getFirst(name);
|
||||
if(cookie == null) {
|
||||
return null;
|
||||
}
|
||||
return cookie.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [ Cookie作用域 ] 里获取一个值 (最后一个此名称的)
|
||||
* @param name 键
|
||||
* @return 值
|
||||
*/
|
||||
@Override
|
||||
public String getCookieLastValue(String name){
|
||||
String value = null;
|
||||
String cookieStr = getHeader("Cookie");
|
||||
if(SaFoxUtil.isNotEmpty(cookieStr)) {
|
||||
String[] cookieItems = cookieStr.split(";");
|
||||
for (String item : cookieItems) {
|
||||
String[] kv = item.split("=");
|
||||
if (kv.length == 2) {
|
||||
if (kv[0].trim().equals(name)) {
|
||||
value = kv[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
||||
// 此种写法无法获取到最后一个 Cookie,WebFlux 底层代码应该是有bug,前端提交多个同名Cookie时只能解析出第一个来
|
||||
// List<HttpCookie> cookies = request.getCookies().get(name);
|
||||
// if(cookies.isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
// return cookies.get(cookies.size() - 1).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求path (不包括上下文名称)
|
||||
*/
|
||||
@Override
|
||||
public String getRequestPath() {
|
||||
return ApplicationInfo.cutPathPrefix(request.getPath().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的url,例:http://xxx.com/test
|
||||
* @return see note
|
||||
*/
|
||||
public String getUrl() {
|
||||
String currDomain = SaManager.getConfig().getCurrDomain();
|
||||
if( ! SaFoxUtil.isEmpty(currDomain)) {
|
||||
return currDomain + this.getRequestPath();
|
||||
}
|
||||
return request.getURI().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的类型
|
||||
*/
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return request.getMethod().name();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询请求 host
|
||||
*/
|
||||
@Override
|
||||
public String getHost() {
|
||||
return request.getURI().getHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转发请求
|
||||
*/
|
||||
@Override
|
||||
public Object forward(String path) {
|
||||
ServerWebExchange exchange = SaReactorSyncHolder.getExchange();
|
||||
WebFilterChain chain = exchange.getAttribute(SaReactorHolder.CHAIN_KEY);
|
||||
|
||||
ServerHttpRequest newRequest = request.mutate().path(path).build();
|
||||
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
|
||||
|
||||
return chain.filter(newExchange);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.model;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
|
||||
/**
|
||||
* 对 SaResponse 包装类的实现(Reactor 响应式编程版)
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
public class SaResponseForReactor implements SaResponse {
|
||||
|
||||
/**
|
||||
* 底层Response对象
|
||||
*/
|
||||
protected ServerHttpResponse response;
|
||||
|
||||
/**
|
||||
* 实例化
|
||||
* @param response response对象
|
||||
*/
|
||||
public SaResponseForReactor(ServerHttpResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取底层源对象
|
||||
*/
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置响应状态码
|
||||
*/
|
||||
@Override
|
||||
public SaResponse setStatus(int sc) {
|
||||
response.setStatusCode(HttpStatus.valueOf(sc));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在响应头里写入一个值
|
||||
*/
|
||||
@Override
|
||||
public SaResponse setHeader(String name, String value) {
|
||||
response.getHeaders().set(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在响应头里添加一个值
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse addHeader(String name, String value) {
|
||||
response.getHeaders().add(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向
|
||||
*/
|
||||
@Override
|
||||
public Object redirect(String url) {
|
||||
response.setStatusCode(HttpStatus.FOUND);
|
||||
response.getHeaders().setLocation(URI.create(url));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.model;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
|
||||
/**
|
||||
* 对 SaStorage 包装类的实现(Reactor 响应式编程版)
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
public class SaStorageForReactor implements SaStorage {
|
||||
|
||||
/**
|
||||
* 底层 ServerWebExchange 对象
|
||||
*/
|
||||
protected ServerWebExchange exchange;
|
||||
|
||||
/**
|
||||
* 实例化
|
||||
* @param exchange exchange对象
|
||||
*/
|
||||
public SaStorageForReactor(ServerWebExchange exchange) {
|
||||
this.exchange = exchange;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取底层源对象
|
||||
*/
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return exchange;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [Request作用域] 里写入一个值
|
||||
*/
|
||||
@Override
|
||||
public SaStorageForReactor set(String key, Object value) {
|
||||
exchange.getAttributes().put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [Request作用域] 里获取一个值
|
||||
*/
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
return exchange.getAttributes().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [Request作用域] 里删除一个值
|
||||
*/
|
||||
@Override
|
||||
public SaStorageForReactor delete(String key) {
|
||||
exchange.getAttributes().remove(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Sa-Token 集成 SpringBoot4 的各个组件
|
||||
* Sa-Token 集成 Reactor 响应式编程的各个组件
|
||||
*/
|
||||
package cn.dev33.satoken;
|
||||
package cn.dev33.satoken.reactor;
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.spring;
|
||||
|
||||
import cn.dev33.satoken.context.SaTokenContextForThreadLocal;
|
||||
|
||||
/**
|
||||
* <h2> 此为低版本(<1.42.0) 的上下文处理方案,仅做留档,如无必要请勿使用 </h2>
|
||||
*
|
||||
* Sa-Token 上下文处理器 [ Spring Reactor 版本实现 ] ,基于 SaTokenContextForThreadLocal 定制
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.33.0
|
||||
*/
|
||||
public class SaTokenContextForSpringReactor extends SaTokenContextForThreadLocal {
|
||||
|
||||
}
|
||||
@@ -13,18 +13,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.spring;
|
||||
package cn.dev33.satoken.reactor.spring;
|
||||
|
||||
import cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet;
|
||||
import cn.dev33.satoken.filter.SaTokenContextFilterForJakartaServlet;
|
||||
import cn.dev33.satoken.filter.SaTokenCorsFilterForJakartaServlet;
|
||||
import cn.dev33.satoken.reactor.filter.SaFirewallCheckFilterForReactor;
|
||||
import cn.dev33.satoken.reactor.filter.SaTokenContextFilterForReactor;
|
||||
import cn.dev33.satoken.reactor.filter.SaTokenCorsFilterForReactor;
|
||||
import cn.dev33.satoken.spring.pathmatch.SaPathPatternParserUtil;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* 注册 Sa-Token 框架所需要的 Bean
|
||||
*
|
||||
* 注册 Sa-Token 所需要的 Bean
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
@@ -43,8 +43,8 @@ public class SaTokenContextRegister {
|
||||
* @return /
|
||||
*/
|
||||
@Bean
|
||||
public SaTokenContextFilterForJakartaServlet saTokenContextFilterForServlet() {
|
||||
return new SaTokenContextFilterForJakartaServlet();
|
||||
public SaTokenContextFilterForReactor saTokenContextFilterForServlet() {
|
||||
return new SaTokenContextFilterForReactor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,8 @@ public class SaTokenContextRegister {
|
||||
* @return /
|
||||
*/
|
||||
@Bean
|
||||
public SaTokenCorsFilterForJakartaServlet saTokenCorsFilterForJakartaServlet() {
|
||||
return new SaTokenCorsFilterForJakartaServlet();
|
||||
public SaTokenCorsFilterForReactor saTokenCorsFilterForReactor() {
|
||||
return new SaTokenCorsFilterForReactor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,8 +63,8 @@ public class SaTokenContextRegister {
|
||||
* @return /
|
||||
*/
|
||||
@Bean
|
||||
public SaFirewallCheckFilterForJakartaServlet saFirewallCheckFilterForJakartaServlet() {
|
||||
return new SaFirewallCheckFilterForJakartaServlet();
|
||||
public SaFirewallCheckFilterForReactor saFirewallCheckFilterForReactor() {
|
||||
return new SaFirewallCheckFilterForReactor();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.reactor.util;
|
||||
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Reactor 操作工具类
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.42.0
|
||||
*/
|
||||
public class SaReactorOperateUtil {
|
||||
|
||||
/**
|
||||
* 写入结果到输出流
|
||||
* @param exchange /
|
||||
* @param result /
|
||||
* @return /
|
||||
*/
|
||||
public static Mono<Void> writeResult(ServerWebExchange exchange, String result) {
|
||||
// 写入输出流
|
||||
// 请注意此处默认 Content-Type 为 text/plain,如果需要返回 JSON 信息,需要在 return 前自行设置 Content-Type 为 application/json
|
||||
// 例如:SaHolder.getResponse().setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
if(exchange.getResponse().getHeaders().getFirst(SaTokenConsts.CONTENT_TYPE_KEY) == null) {
|
||||
exchange.getResponse().getHeaders().set(SaTokenConsts.CONTENT_TYPE_KEY, SaTokenConsts.CONTENT_TYPE_TEXT_PLAIN);
|
||||
}
|
||||
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(result.getBytes())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
cn.dev33.satoken.reactor.spring.SaTokenContextRegister
|
||||
@@ -36,14 +36,33 @@
|
||||
<artifactId>sa-token-servlet</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-autoconfig -->
|
||||
<!-- sa-token-spring-boot-webmvc-reactor-v2v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jackson: JSON serialization -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- sa-token springboot2 相关依赖版本定义 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot2-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-spring-boot-autoconfig</name>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<description>sa-token-spring-boot-autoconfig</description>
|
||||
<name>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</name>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
<description>sa-token springboot webmvc/reactor v2/v3/v4 common</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -27,12 +27,6 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>5.3.7</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -43,12 +37,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson 序列化、redis集成、SSO、OAuth2 等模块要用到,比较重要所以内置集成 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SSO (optional) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
@@ -80,5 +68,19 @@
|
||||
</dependencies>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- 默认引入 sa-token springboot2 相关依赖版本定义,上层可以继续引入其它版本定义来覆盖本层,Maven 采用就近原则选择依赖版本 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot2-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-starter</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-spring-boot-webmvc-v3v4-common</name>
|
||||
<artifactId>sa-token-spring-boot-webmvc-v3v4-common</artifactId>
|
||||
<description>sa-token springboot webmvc v3v4 common</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring-boot-starter-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jakarta-servlet -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jakarta-servlet</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-webmvc-reactor-v2v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-reactor-v2v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- 默认引入 sa-token springboot3 相关依赖版本定义,上层可以继续引入其它版本定义来覆盖本层,Maven 采用就近原则选择依赖版本 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot3-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -15,63 +15,37 @@
|
||||
<name>sa-token-spring-boot3-starter</name>
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<description>springboot3 integrate sa-token</description>
|
||||
|
||||
<properties>
|
||||
<springboot3.version>3.0.1</springboot3.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring-boot-starter-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jakarta-servlet -->
|
||||
|
||||
<!-- sa-token-spring-boot-webmvc-v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jakarta-servlet</artifactId>
|
||||
<artifactId>sa-token-spring-boot-webmvc-v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-autoconfig -->
|
||||
<!-- sa-token-jackson: JSON serialization for Spring Boot 3 (Jackson 2.x) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<artifactId>sa-token-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${springboot3.version}</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-starter-web -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- sa-token springboot3 相关依赖版本定义 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${springboot3.version}</version>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot3-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot3.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
cn.dev33.satoken.spring.SaTokenContextRegister
|
||||
@@ -15,41 +15,13 @@
|
||||
<name>sa-token-spring-boot4-starter</name>
|
||||
<artifactId>sa-token-spring-boot4-starter</artifactId>
|
||||
<description>springboot4 integrate sa-token</description>
|
||||
|
||||
<properties>
|
||||
<springboot4.version>4.0.3</springboot4.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring-boot-starter-webmvc (Spring Boot 4 recommended, replaces deprecated starter-web) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webmvc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jakarta-servlet -->
|
||||
|
||||
<!-- sa-token-spring-boot-webmvc-v3v4-common -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jakarta-servlet</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-spring-boot-autoconfig (exclude sa-token-jackson, use sa-token-jackson3 for Spring Boot 4) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-autoconfig</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<artifactId>sa-token-spring-boot-webmvc-v3v4-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-jackson3: JSON serialization for Spring Boot 4 (Jackson 3) -->
|
||||
@@ -57,45 +29,22 @@
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jackson3</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-starter-webmvc -->
|
||||
|
||||
<!-- sa-token springboot4 相关依赖版本定义 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webmvc</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
</dependency>
|
||||
<!-- config (optional) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot4.version}</version>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot4-dependencies</artifactId>
|
||||
<version>${revision}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.interceptor;
|
||||
|
||||
import cn.dev33.satoken.exception.BackResultException;
|
||||
import cn.dev33.satoken.exception.StopMatchException;
|
||||
import cn.dev33.satoken.fun.SaParamFunction;
|
||||
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Sa-Token 综合拦截器,提供注解鉴权和路由拦截鉴权能力
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
public class SaInterceptor implements HandlerInterceptor {
|
||||
|
||||
/**
|
||||
* 是否打开注解鉴权
|
||||
*/
|
||||
public boolean isAnnotation = true;
|
||||
|
||||
/**
|
||||
* 认证函数:每次请求执行
|
||||
* <p> 参数:路由处理函数指针
|
||||
*/
|
||||
public SaParamFunction<Object> auth = handler -> {};
|
||||
|
||||
/**
|
||||
* 创建一个 Sa-Token 综合拦截器,默认带有注解鉴权能力
|
||||
*/
|
||||
public SaInterceptor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个 Sa-Token 综合拦截器,默认带有注解鉴权能力
|
||||
* @param auth 认证函数,每次请求执行
|
||||
*/
|
||||
public SaInterceptor(SaParamFunction<Object> auth) {
|
||||
this.auth = auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否打开注解鉴权
|
||||
* @param isAnnotation /
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaInterceptor isAnnotation(boolean isAnnotation) {
|
||||
this.isAnnotation = isAnnotation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入[认证函数]: 每次请求执行
|
||||
* @param auth /
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaInterceptor setAuth(SaParamFunction<Object> auth) {
|
||||
this.auth = auth;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// ----------------- 验证方法 -----------------
|
||||
|
||||
/**
|
||||
* 每次请求之前触发的方法
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
|
||||
try {
|
||||
|
||||
// 这里必须确保 handler 是 HandlerMethod 类型时,才能进行注解鉴权
|
||||
if(isAnnotation && handler instanceof HandlerMethod) {
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
}
|
||||
|
||||
// Auth 校验
|
||||
auth.run(handler);
|
||||
|
||||
} catch (StopMatchException e) {
|
||||
// StopMatchException 异常代表:停止匹配,进入Controller
|
||||
|
||||
} catch (BackResultException e) {
|
||||
// BackResultException 异常代表:停止匹配,向前端输出结果
|
||||
// 请注意此处默认 Content-Type 为 text/plain,如果需要返回 JSON 信息,需要在 back 前自行设置 Content-Type 为 application/json
|
||||
// 例如:SaHolder.getResponse().setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
if(response.getContentType() == null) {
|
||||
response.setContentType("text/plain; charset=utf-8");
|
||||
}
|
||||
response.getWriter().print(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 通过验证
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.spring;
|
||||
|
||||
import cn.dev33.satoken.context.SaTokenContextForReadOnly;
|
||||
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.servlet.model.SaRequestForServlet;
|
||||
import cn.dev33.satoken.servlet.model.SaResponseForServlet;
|
||||
import cn.dev33.satoken.servlet.model.SaStorageForServlet;
|
||||
|
||||
/**
|
||||
* <h2> 此为低版本(<1.42.0) 的上下文处理方案,基于 Spring 内部工具类 RequestContextHolder 读写上下文,仅做留档,如无必要请勿使用 </h2>
|
||||
*
|
||||
* Sa-Token 上下文处理器 [ SpringBoot4 Jakarta Servlet 版 ],在 SpringBoot4 中使用 Sa-Token 时,必须注入此实现类,否则会出现上下文无效异常
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
public class SaTokenContextForSpringInJakartaServlet implements SaTokenContextForReadOnly {
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Request 包装对象
|
||||
*/
|
||||
@Override
|
||||
public SaRequest getRequest() {
|
||||
return new SaRequestForServlet(SpringMVCUtil.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Response 包装对象
|
||||
*/
|
||||
@Override
|
||||
public SaResponse getResponse() {
|
||||
return new SaResponseForServlet(SpringMVCUtil.getResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Storage 包装对象
|
||||
*/
|
||||
@Override
|
||||
public SaStorage getStorage() {
|
||||
return new SaStorageForServlet(SpringMVCUtil.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断:在本次请求中,此上下文是否可用。
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return SpringMVCUtil.isWeb();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.spring;
|
||||
|
||||
import cn.dev33.satoken.exception.NotWebContextException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
/**
|
||||
* SpringMVC 相关操作工具类,快速获取当前会话的 HttpServletRequest、HttpServletResponse 对象
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.34.0
|
||||
*/
|
||||
public class SpringMVCUtil {
|
||||
|
||||
private SpringMVCUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话的 request
|
||||
* @return request
|
||||
*/
|
||||
public static HttpServletRequest getRequest() {
|
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if(servletRequestAttributes == null) {
|
||||
throw new NotWebContextException("非 web 上下文无法获取 HttpServletRequest");
|
||||
}
|
||||
return servletRequestAttributes.getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话的 response
|
||||
* @return response
|
||||
*/
|
||||
public static HttpServletResponse getResponse() {
|
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if(servletRequestAttributes == null) {
|
||||
throw new NotWebContextException("非 web 上下文无法获取 HttpServletRequest");
|
||||
}
|
||||
return servletRequestAttributes.getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前是否处于 Web 上下文中
|
||||
* @return request
|
||||
*/
|
||||
public static boolean isWeb() {
|
||||
return RequestContextHolder.getRequestAttributes() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,6 +43,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>2.5.12</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
Reference in New Issue
Block a user