mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-05-14 21:02:09 +08:00
docs: 新增QA:解决低版本 SpringBoot (<2.2.0) 引入 Sa-Token 报错的问题
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
<module>sa-token-demo-solon-redisson</module>
|
<module>sa-token-demo-solon-redisson</module>
|
||||||
<module>sa-token-demo-springboot</module>
|
<module>sa-token-demo-springboot</module>
|
||||||
<module>sa-token-demo-springboot3-redis</module>
|
<module>sa-token-demo-springboot3-redis</module>
|
||||||
|
<module>sa-token-demo-springboot-low-version</module>
|
||||||
<module>sa-token-demo-springboot-redis</module>
|
<module>sa-token-demo-springboot-redis</module>
|
||||||
<module>sa-token-demo-springboot-redisson</module>
|
<module>sa-token-demo-springboot-redisson</module>
|
||||||
<module>sa-token-demo-ssm</module>
|
<module>sa-token-demo-ssm</module>
|
||||||
|
|||||||
146
sa-token-demo/sa-token-demo-springboot-low-version/pom.xml
Normal file
146
sa-token-demo/sa-token-demo-springboot-low-version/pom.xml
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<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-springboot-low-version</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<!-- SpringBoot -->
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<!-- 可以 -->
|
||||||
|
<!--<version>2.2.0.RELEASE</version>-->
|
||||||
|
<!-- 不可以 -->
|
||||||
|
<version>2.1.18.RELEASE</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<!-- 定义 Sa-Token 版本号 -->
|
||||||
|
<properties>
|
||||||
|
<sa-token.version>1.41.0</sa-token.version>
|
||||||
|
<java.run.main.class>com.pj.SaTokenApplication</java.run.main.class>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringBoot依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token 权限认证, 在线文档:https://sa-token.cc/ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||||
|
<version>${sa-token.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.36</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token 整合 RedisTemplate -->
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- SpringBoot 版本过低时,需要追加的包 (低于2.2.0时,不包含2.2.0本身) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-core</artifactId>
|
||||||
|
<version>2.17.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
<version>2.17.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.17.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- @ConfigurationProperties -->
|
||||||
|
<!--<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>-->
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<!-- 构建配置 -->
|
||||||
|
<build>
|
||||||
|
<!-- 配置资源目录 -->
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/java</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.xml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.*</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
|
<mainClass>${java.run.main.class}</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<!-- 拷贝依赖的jar包到lib目录 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>
|
||||||
|
${project.build.directory}/lib
|
||||||
|
</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</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 测试
|
||||||
|
* @author click33
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SaTokenApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SaTokenApplication.class, args);
|
||||||
|
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||||
|
// System.out.println(StpUtil.getSessionByLoginId(10001));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.pj.current;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局异常处理
|
||||||
|
*/
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalException {
|
||||||
|
|
||||||
|
// 全局异常拦截(拦截项目中的所有异常)
|
||||||
|
@ExceptionHandler
|
||||||
|
public SaResult handlerException(Exception e, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
|
||||||
|
// 打印堆栈,以供调试
|
||||||
|
System.out.println("全局异常---------------");
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
// 返回给前端
|
||||||
|
return SaResult.error(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.pj.satoken;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.context.SaHolder;
|
||||||
|
import cn.dev33.satoken.filter.SaServletFilter;
|
||||||
|
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||||
|
import cn.dev33.satoken.router.SaHttpMethod;
|
||||||
|
import cn.dev33.satoken.router.SaRouter;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Sa-Token 权限认证] 配置类
|
||||||
|
* @author click33
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册 Sa-Token 拦截器打开注解鉴权功能
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
// 注册 Sa-Token 拦截器打开注解鉴权功能
|
||||||
|
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册 [Sa-Token 全局过滤器]
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public SaServletFilter getSaServletFilter() {
|
||||||
|
return new SaServletFilter()
|
||||||
|
|
||||||
|
// 指定 [拦截路由] 与 [放行路由]
|
||||||
|
.addInclude("/**")// .addExclude("/favicon.ico")
|
||||||
|
|
||||||
|
// 认证函数: 每次请求执行
|
||||||
|
.setAuth(obj -> {
|
||||||
|
// 输出 API 请求日志,方便调试代码
|
||||||
|
// SaManager.getLog().debug("----- 请求path={} 提交token={}", SaHolder.getRequest().getRequestPath(), StpUtil.getTokenValue());
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// 异常处理函数:每次认证函数发生异常时执行此函数
|
||||||
|
.setError(e -> {
|
||||||
|
System.out.println("---------- sa全局异常 ");
|
||||||
|
e.printStackTrace();
|
||||||
|
return SaResult.error(e.getMessage());
|
||||||
|
})
|
||||||
|
|
||||||
|
// 前置函数:在每次认证函数之前执行
|
||||||
|
.setBeforeAuth(obj -> {
|
||||||
|
// ---------- 设置一些安全响应头 ----------
|
||||||
|
SaHolder.getResponse()
|
||||||
|
// 服务器名称
|
||||||
|
.setServer("sa-server")
|
||||||
|
// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
|
||||||
|
.setHeader("X-Frame-Options", "SAMEORIGIN")
|
||||||
|
// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
|
||||||
|
.setHeader("X-XSS-Protection", "1; mode=block")
|
||||||
|
// 禁用浏览器内容嗅探
|
||||||
|
.setHeader("X-Content-Type-Options", "nosniff")
|
||||||
|
|
||||||
|
// ---------- 设置跨域响应头 ----------
|
||||||
|
// 允许指定域访问跨域资源
|
||||||
|
.setHeader("Access-Control-Allow-Origin", "*")
|
||||||
|
// 允许所有请求方式
|
||||||
|
.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
|
||||||
|
// 有效时间
|
||||||
|
.setHeader("Access-Control-Max-Age", "3600")
|
||||||
|
// 允许的header参数
|
||||||
|
.setHeader("Access-Control-Allow-Headers", "*");
|
||||||
|
|
||||||
|
// 如果是预检请求,则立即返回到前端
|
||||||
|
SaRouter.match(SaHttpMethod.OPTIONS)
|
||||||
|
.free(r -> System.out.println("--------OPTIONS预检请求,不做处理"))
|
||||||
|
.back();
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.session.SaTerminalInfo;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录测试
|
||||||
|
* @author click33
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/acc/")
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
// 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||||
|
@RequestMapping("doLogin")
|
||||||
|
public SaResult doLogin(String name, String pwd) {
|
||||||
|
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||||
|
if("zhang".equals(name) && "123456".equals(pwd)) {
|
||||||
|
StpUtil.login(10001);
|
||||||
|
StpUtil.getTokenSession();
|
||||||
|
return SaResult.ok("登录成功");
|
||||||
|
}
|
||||||
|
return SaResult.error("登录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询登录状态 ---- http://localhost:8081/acc/isLogin
|
||||||
|
@RequestMapping("isLogin")
|
||||||
|
public SaResult isLogin() {
|
||||||
|
return SaResult.ok("是否登录:" + StpUtil.isLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验登录 ---- http://localhost:8081/acc/checkLogin
|
||||||
|
@RequestMapping("checkLogin")
|
||||||
|
public SaResult checkLogin() {
|
||||||
|
StpUtil.checkLogin();
|
||||||
|
return SaResult.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
|
||||||
|
@RequestMapping("tokenInfo")
|
||||||
|
public SaResult tokenInfo() {
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询账号登录设备信息 ---- http://localhost:8081/acc/terminalInfo
|
||||||
|
@RequestMapping("terminalInfo")
|
||||||
|
public SaResult terminalInfo() {
|
||||||
|
System.out.println("账号 10001 登录设备信息:");
|
||||||
|
List<SaTerminalInfo> terminalList = StpUtil.getTerminalListByLoginId(10001);
|
||||||
|
for (SaTerminalInfo ter : terminalList) {
|
||||||
|
System.out.println("登录index=" + ter.getIndex() + ", 设备type=" + ter.getDeviceType() + ", token=" + ter.getTokenValue() + ", 登录time=" + ter.getCreateTime());
|
||||||
|
}
|
||||||
|
return SaResult.data(terminalList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 测试注销 ---- http://localhost:8081/acc/logout
|
||||||
|
@RequestMapping("logout")
|
||||||
|
public SaResult logout() {
|
||||||
|
StpUtil.login(10001, SaLoginParameter.create().setIsConcurrent(false));
|
||||||
|
return SaResult.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# 端口
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
|
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
|
||||||
|
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: 10s
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
# 连接池最大连接数
|
||||||
|
max-active: 200
|
||||||
|
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||||
|
max-wait: -1ms
|
||||||
|
# 连接池中的最大空闲连接
|
||||||
|
max-idle: 10
|
||||||
|
# 连接池中的最小空闲连接
|
||||||
|
min-idle: 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -565,9 +565,34 @@ public class SaTokenContextByPatternsRequestCondition extends SaTokenContextForS
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Q:过低的 SpringBoot 版本引入 Sa-Token 后报错
|
||||||
|
|
||||||
|
在低于 2.2.0 时 (不包含2.2.0本身) 的 SpringBoot 项目中引入 Sa-Token 后,项目启动时会报错:
|
||||||
|
|
||||||
|
``` txt
|
||||||
|
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cn.dev33.satoken.spring.SaBeanInject': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [cn.dev33.satoken.spring.SaBeanInject]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator
|
||||||
|
```
|
||||||
|
|
||||||
|
这是由于缺少 jackson 相关依赖导致的,可以手动添加以下依赖来解决:
|
||||||
|
|
||||||
|
``` xml
|
||||||
|
<!-- SpringBoot 版本过低时,需要追加的包 (低于 2.2.0 时,不包含 2.2.0 本身) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-core</artifactId>
|
||||||
|
<version>2.17.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
<version>2.17.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.17.3</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user