Compare commits

..

69 Commits

Author SHA1 Message Date
click33
004a1b7ed9 补全目录 2024-05-12 15:59:03 +08:00
click33
bd92fbbed9 修正更新日志 2024-05-12 14:33:51 +08:00
click33
35cb81085c 修复 sa-token-sso 部分问题 2024-05-12 12:40:05 +08:00
click33
8f467bbc9c StpUtil.getTokenSession() 时若未提供 token 将直接抛出异常 2024-05-12 08:59:02 +08:00
刘潇
43c9452fb2 !300 调整 solon 的 dao 适配
Merge pull request !300 from 西东/dev
2024-05-11 09:57:34 +00:00
noear
81709bcef8 取消 SaSessionForJson (发现没必要了) 2024-05-11 17:55:27 +08:00
刘潇
fcab8b876e !299 优化 solon 相关的 SaTokenDaoOfRedisJson 序列化处理
Merge pull request !299 from 西东/dev
2024-05-11 09:42:48 +00:00
noear
1a62c391ea 优化 solon 相关的 SaTokenDaoOfRedisJson 序列化处理 2024-05-11 17:39:58 +08:00
click33
1c05958d51 修正 solon 相关 demo 案例 2024-05-11 17:11:41 +08:00
click33
1850130e11 sa-token-sso model 类增加 implements Serializable,以便完成序列化存储 2024-05-11 17:11:26 +08:00
click33
4be4ee54c2 修复部分场景下不能正常创建 token-session 的问题 2024-05-11 16:17:25 +08:00
click33
dd533fba8e /sso/logout 接口 self 格式设置响应头,以适配 solon 下集成 sso 插件可以正常跳转路径 2024-05-11 15:56:56 +08:00
click33
54114ebac6 升级优化一下 solon 相关集成 demo 2024-05-11 15:37:02 +08:00
刘潇
26bf2bd478 !298 优化 solon 相关的 demo 代码
Merge pull request !298 from 西东/dev
2024-05-11 05:59:23 +00:00
noear
e024457405 优化 solon 相关的 demo 代码 2024-05-11 13:46:16 +08:00
noear
1ab5bbe3d6 优化 solon 的适配 2024-05-11 13:45:40 +08:00
click33
89a69e5624 新增问答Q 2024-05-10 16:32:36 +08:00
click33
c3bd2018a2 补全 update-log 2024-05-10 16:24:40 +08:00
click33
535c8e972f 修复 StpUtil.getLoginId(T defaultValue) 传入 null 时无法正确返回值的bug 2024-05-10 16:16:52 +08:00
click33
b4baa4229f 修复eff为null时报空指针的问题 2024-05-10 14:32:45 +08:00
click33
bdac07d7a0 补全 update-log 2024-05-10 13:11:27 +08:00
click33
b2416ae43d 修复jwt部分模式不能正确创建 token-session 的问题 2024-05-10 13:08:52 +08:00
click33
c5c3253171 修复创建匿名 token-session 不能持久化存储的问题 2024-05-10 12:40:42 +08:00
click33
6d4496897d 优化:二级认证校验之前必须先通过登录认证校验 2024-05-10 10:55:47 +08:00
click33
ea546c7adb 修正文档 2024-05-10 09:44:05 +08:00
click33
f612c87e3a @SaCheckOr注解增加补全@SaCheckHttpDigest校验 2024-05-10 09:41:06 +08:00
click33
adb600d643 优化 token 读取策略,空字符串将视为没有提交token 2024-05-10 09:21:11 +08:00
click33
c508e99281 sa-token-bom 补全缺失依赖 2024-05-10 07:48:52 +08:00
click33
d6f2be4a2e 补全更新日志 2024-05-09 11:06:34 +08:00
click33
c169721ebf 禁止 allow-url 配置项 * 符号出现在中间位置,因为这有可能导致校验被绕过 2024-05-09 11:04:50 +08:00
click33
f35a6f6ad8 修复利用@字符可以绕过域名允许列表校验的漏洞 2024-05-09 10:15:57 +08:00
click33
aa47362cfa 更新赞助案例 2024-05-08 18:12:40 +08:00
click33
55821d09c6 新增用户数据同步/迁移方案的建议 2024-05-08 17:29:04 +08:00
click33
b23aa55ffa 新增 checkTicketAppendData 策略函数,用于在校验 ticket 后,给 sso-client 端追加返回信息 2024-05-08 17:21:41 +08:00
click33
e781664840 更新赞助者名单 2024-05-07 17:06:10 +08:00
click33
9261a2687c 优化 readme 2024-05-07 16:37:00 +08:00
click33
7556796eaa 优化readme 2024-05-07 16:29:14 +08:00
click33
278dd42695 优化 readme 2024-05-07 15:53:47 +08:00
click33
1bbf127b95 优化文档 2024-05-06 16:02:32 +08:00
click33
73843741af 完善多账号体系鉴权文档 2024-05-06 13:37:23 +08:00
click33
60fdc4ca2a 补全缺失方法 2024-05-06 13:37:04 +08:00
click33
ce40fe2dad v1.38.0 update 2024-05-06 12:01:07 +08:00
click33
cc9fe4c08b 补全遗漏项目 2024-05-06 10:57:57 +08:00
click33
b926bad13d 移除过期配置项 2024-05-06 10:34:00 +08:00
click33
83ac203631 优化文档 2024-05-06 10:33:42 +08:00
click33
f4dda6eb6c 完善文档 2024-05-05 12:45:04 +08:00
click33
78fd26e9db 优化文档 2024-05-05 12:40:05 +08:00
click33
9e37896bb0 补全缺失的 clean 项目 2024-05-05 12:39:54 +08:00
click33
c1bc858f14 优化文档 2024-05-05 12:30:14 +08:00
click33
42d94827c1 完善 Http Digest 认证文档 2024-05-05 12:27:49 +08:00
click33
1ba8d6f8d4 新增问卷调查弹窗提示 2024-05-05 06:44:28 +08:00
click33
9680d6cb9f 更新 赞助者列表 2024-05-05 05:47:34 +08:00
click33
ce4d12b0ca 补全 Dromara 社区项目 2024-05-05 04:24:01 +08:00
click33
b92ba4de87 优化文档和demo示例 2024-05-04 11:02:22 +08:00
click33
7f5ae11961 优化demo示例 2024-05-04 09:48:31 +08:00
click33
c0a993a0f5 更新 Sa-Token 问卷调查 2024-05-04 08:54:23 +08:00
click33
2eacec9539 补齐 sa-token-spring-aop 模块中遗漏监听的注解 2024-05-04 05:58:18 +08:00
click33
21948fbf7e 文字逐字打印效果.. 2024-05-04 05:31:48 +08:00
click33
c850874e49 首页介绍文字增加逐字打印效果 2024-05-04 04:49:51 +08:00
click33
64abd69715 新增 autoRenewTimeout 配置项:是否在每次下发 ticket 时,自动续期 token 的有效期(根据全局 timeout 值) 2024-05-03 16:14:40 +08:00
click33
5a7463dc91 优化登录有效期策略,SSO Client 端登录时将延续 SSO Server 端的会话剩余有效期 2024-05-03 14:22:27 +08:00
click33
cf1f255a4a 新增 homeRoute 配置项:在 /sso/auth 登录后不指定 redirect 参数的情况下默认跳转的路由 2024-05-03 04:04:52 +08:00
click33
4c216069aa 匿名 client 将不再能解析出所有应用的 client 2024-05-02 10:36:54 +08:00
click33
7ee27add84 修复 sso nosdk demo 不正确之处.. 2024-05-02 07:42:54 +08:00
click33
27618484dc 修复 sso nosdk demo 不正确之处 2024-05-02 07:42:20 +08:00
click33
8d6b648d4b 新增不同 SSO Client 配置不同秘钥的方案 2024-05-02 07:17:11 +08:00
click33
c52fd9c86f 优化 sso 章节文档 2024-05-01 11:33:17 +08:00
click33
818c1cb4eb 优化sso章节文档和demo示例 2024-05-01 11:14:35 +08:00
click33
14a97a1fcb sso 模块新增 maxRegClient 属性,用于控制模式三下 client 注册数量 2024-05-01 05:53:18 +08:00
167 changed files with 2664 additions and 1058 deletions

137
README.md
View File

@@ -1,7 +1,7 @@
<p align="center">
<img alt="logo" src="https://sa-token.cc/logo.png" width="150" height="150">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">Sa-Token v1.37.0</h1>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">Sa-Token v1.38.0</h1>
<h4 align="center">一个轻量级 Java 权限认证框架,让鉴权变得简单、优雅!</h4>
<p align="center">
<a href="https://gitee.com/dromara/sa-token/stargazers"><img src="https://gitee.com/dromara/sa-token/badge/star.svg?theme=gvp"></a>
@@ -12,20 +12,20 @@
<a href="https://github.com/dromara/sa-token/issues"><img src="https://img.shields.io/github/issues/dromara/sa-token.svg?style=flat-square&logo=GitHub"></a>
<a href="https://github.com/dromara/sa-token/blob/master/LICENSE"><img src="https://img.shields.io/github/license/dromara/sa-token.svg?style=flat-square"></a>
</p>
<!-- <p align="center">学习测试请拉取 master 分支dev 是在开发分支 (在根目录执行 `git checkout master`)</p> -->
<p align="center"><a href="https://sa-token.cc" target="_blank">在线文档https://sa-token.cc</a></p>
---
## 前言:
- [在线文档https://sa-token.cc](https://sa-token.cc)
### Sa-Token 介绍
- 注:学习测试请拉取 master 分支dev 是开发分支,有很多特性并不稳定(在项目根目录执行 `git checkout master`
- 开源不易,点个 star 鼓励一下吧!
Sa-Token 是一个轻量级 Java 权限认证框架目前拥有五大核心模块登录认证、权限认证、单点登录、OAuth2.0、微服务鉴权
## Sa-Token 介绍
**Sa-Token** 是一个轻量级 Java 权限认证框架主要解决登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。
<details>
<summary><b>简单示例展示:(点击展开 / 折叠)</b></summary>
Sa-Token 旨在以简单、优雅的方式完成系统的权限认证部分,以登录认证为例,你只需要:
@@ -79,62 +79,81 @@ registry.addInterceptor(new SaInterceptor(handler -> {
当你受够 Shiro、SpringSecurity 等框架的三拜九叩之后你就会明白相对于这些传统老牌框架Sa-Token 的 API 设计是多么的简单、优雅!
</details>
## Sa-Token 功能模块一览
<details>
<summary> <b>核心模块一览:(点击展开 / 折叠)</b> </summary>
Sa-Token 目前主要五大功能模块登录认证、权限认证、单点登录、OAuth2.0、微服务鉴权
- **登录认证** —— 单端登录、多端登录、同端互斥登录、七天内免登录
- **权限认证** —— 权限认证、角色认证、会话二级认证。
- **踢人下线** —— 根据账号id踢人下线、根据Token值踢人下线。
- **注解式鉴权** —— 优雅的将鉴权与业务代码分离。
- **路由拦截式鉴权** —— 根据路由拦截鉴权,可适配 restful 模式。
- **Session会话** —— 全端共享Session,单端独享Session,自定义Session,方便的存取值。
- **持久层扩展** —— 可集成 Redis重启数据不丢失。
- **前后台分离** —— APP、小程序等不支持 Cookie 的终端也可以轻松鉴权。
- **Token风格定制** —— 内置六种 Token 风格,还可:自定义 Token 生成策略。
- **记住我模式** —— 适配 [记住我] 模式,重启浏览器免验证。
- **二级认证** —— 在已登录的基础上再次认证,保证安全性。
- **模拟他人账号** —— 实时操作任意用户状态数据。
- **临时身份切换** —— 将会话身份临时切换为其它账号。
- **同端互斥登录** —— 像QQ一样手机电脑同时在线但是两个手机上互斥登录。
- **账号封禁** —— 登录封禁、按照业务分类封禁、按照处罚阶梯封禁。
- **密码加密** —— 提供基础加密算法,可快速 MD5、SHA1、SHA256、AES 加密。
- **会话查询** —— 提供方便灵活的会话查询接口。
- **Http Basic认证** —— 一行代码接入 Http Basic、Digest 认证。
- **全局侦听器** —— 在用户登陆、注销、被踢下线等关键性操作时进行一些AOP操作。
- **全局过滤器** —— 方便的处理跨域,全局设置安全响应头等操作。
- **多账号体系认证** —— 一个系统多套账号分开鉴权(比如商城的 User 表和 Admin 表)
- **单点登录** —— 内置三种单点登录模式同域、跨域、同Redis、跨Redis、前后端分离等架构都可以搞定。
- **单点注销** —— 任意子系统内发起注销,即可全端下线。
- **OAuth2.0认证** —— 轻松搭建 OAuth2.0 服务支持openid模式 。
- **分布式会话** —— 提供共享数据中心分布式会话方案。
- **微服务网关鉴权** —— 适配Gateway、ShenYu、Zuul等常见网关的路由拦截认证。
- **RPC调用鉴权** —— 网关转发鉴权RPC调用鉴权让服务调用不再裸奔
- **临时Token认证** —— 解决短时间的 Token 授权问题。
- **独立Redis** —— 将权限缓存与业务缓存分离。
- **Quick快速登录认证** —— 为项目零代码注入一个登录页面。
- **标签方言** —— 提供 Thymeleaf 标签方言集成包,提供 beetl 集成示例。
- **jwt集成** —— 提供三种模式的 jwt 集成方案,提供 token 扩展参数能力。
- **RPC调用状态传递** —— 提供 dubbo、grpc 等集成包在RPC调用时登录状态不丢失。
- **参数签名** —— 提供跨系统API调用签名校验模块防参数篡改防请求重放。
- **自动续签** —— 提供两种Token过期策略灵活搭配使用还可自动续签。
- **开箱即用** —— 提供SpringMVC、WebFlux、Solon 等常见框架集成包,开箱即用。
- **最新技术栈** —— 适配最新技术栈:支持 SpringBoot 3.xjdk 17。
- **登录认证** —— 单端登录、多端登录、同端互斥登录、七天内免登录
- **权限认证** —— 权限认证、角色认证、会话二级认证
- **Session会话** —— 全端共享Session、单端独享Session、自定义Session
- **踢人下线** —— 根据账号id踢人下线、根据Token值踢人下线
- **账号封禁** —— 登录封禁、按照业务分类封禁、按照处罚阶梯封禁
- **持久层扩展** —— 可集成Redis、Memcached等专业缓存中间件重启数据不丢失
- **分布式会话** —— 提供jwt集成、共享数据中心两种分布式会话方案
- **微服务网关鉴权** —— 适配Gateway、ShenYu、Zuul等常见网关的路由拦截认证
- **单点登录** —— 内置三种单点登录模式无论是否跨域、是否共享Redis都可以搞定
- **OAuth2.0认证** —— 轻松搭建 OAuth2.0 服务支持openid模式
- **二级认证** —— 在已登录的基础上再次认证,保证安全性
- **Basic认证** —— 一行代码接入 Http Basic 认证
- **独立Redis** —— 将权限缓存与业务缓存分离
- **临时Token认证** —— 解决短时间的Token授权问题
- **模拟他人账号** —— 实时操作任意用户状态数据
- **临时身份切换** —— 将会话身份临时切换为其它账号
- **前后台分离** —— APP、小程序等不支持Cookie的终端
- **同端互斥登录** —— 像QQ一样手机电脑同时在线但是两个手机上互斥登录
- **多账号认证体系** —— 比如一个商城项目的user表和admin表分开鉴权
- **Token风格定制** —— 内置六种Token风格还可自定义Token生成策略、自定义Token前缀
- **注解式鉴权** —— 优雅的将鉴权与业务代码分离
- **路由拦截式鉴权** —— 根据路由拦截鉴权可适配restful模式
- **自动续签** —— 提供两种Token过期策略灵活搭配使用还可自动续签
- **会话治理** —— 提供方便灵活的会话查询接口
- **记住我模式** —— 适配[记住我]模式,重启浏览器免验证
- **密码加密** —— 提供密码加密模块可快速MD5、SHA1、SHA256、AES、RSA加密
- **全局侦听器** —— 在用户登陆、注销、被踢下线等关键性操作时进行一些AOP操作
- **开箱即用** —— 提供SpringMVC、WebFlux等常见web框架starter集成包真正的开箱即用
</details>
功能结构图:
![sa-token-js](https://color-test.oss-cn-qingdao.aliyuncs.com/sa-token/x/sa-token-js4.png)
## Sa-Token-SSO 单点登录
Sa-Token-SSO 由简入难划分为三种模式,解决不同架构下的 SSO 接入问题:
### SSO 单点登录
Sa-Token SSO 分为三种模式,解决同域、跨域、共享Redis、跨Redis、前后端一体、前后端分离……等不同架构下的 SSO 接入问题:
| 系统架构 | 采用模式 | 简介 | 文档链接 |
| :-------- | :-------- | :-------- | :-------- |
| 前端同域 + 后端同 Redis | 模式一 | 共享Cookie同步会话 | [文档](https://sa-token.cc/doc.html#/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso1-client) |
| 前端同域 + 后端同 Redis | 模式一 | 共享Cookie同步会话 | [文档](https://sa-token.cc/doc.html#/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso1-client) |
| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](https://sa-token.cc/doc.html#/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso2-client) |
| 前端不同域 + 后端 不同Redis | 模式三 | Http请求获取会话 | [文档](https://sa-token.cc/doc.html#/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso3-client) |
| 前端不同域 + 后端 不同Redis | 模式三 | Http请求获取会话 | [文档](https://sa-token.cc/doc.html#/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso3-client) |
1. 前端同域:就是指多个系统可以部署在同一个主域名之下,比如:`c1.domain.com`、`c2.domain.com`、`c3.domain.com`
2. 后端同Redis就是指多个系统可以连接同一个Redis。PS这里并不需要把所有项目数据都放在一个Redis中Sa-Token提供 **`[权限缓存与业务缓存分离]`** 的解决方案,详情戳:[Alone独立Redis插件](https://sa-token.cc/doc.html#/plugin/alone-redis)
3. 如果既无法做到前端同域也无法做到后端同Redis那么只能走模式三Http请求获取会话Sa-Token对SSO提供了完整的封装你只需要按照示例从文档上复制几段代码便可以轻松集成
2. 后端同Redis就是指多个系统可以连接同一个Redis。(此处并非要所有项目数据都放在一个Redis中Sa-Token提供 **`[权限缓存与业务缓存分离]`** 的解决方案
3. 如果既无法做到前端同域也无法做到后端同Redis可以走模式三Http请求校验 ticket 获取会话。
4. 提供 NoSdk 模式示例,不使用 Sa-Token 的系统也可以对接。
5. 提供 sso-server 接口文档,不使用 java 语言的系统也可以对接。
6. 提供前后端分离整合方案:无论是 sso-server 还是 sso-client 的前后端分离都可以整合。
7. 提供安全校验域名校验、ticket校验、参数签名校验有效防 ticket 劫持,防请求重放等攻击。
8. 参数防丢笔者曾试验多个SSO框架均有参数丢失情况比如登录前是`http://a.com?id=1&name=2`,登录成功后就变成了:`http://a.com?id=1`Sa-Token-SSO 内有专门算法保证了参数不丢失,登录成功后精准原路返回。
9. 提供用户数据同步/迁移方案的建议:开发前统一迁移、运行时实时数据同步、根据关联字段匹配、根据 center_id 字段匹配等。
10. 提供直接可运行的 demo 示例,帮助你快速熟悉 SSO 大致登录流程。
## Sa-Token-OAuth2 授权认证
Sa-OAuth2 模块分为四种授权模式,解决不同场景下的授权需求
### OAuth2 授权认证
Sa-Token-OAuth2 模块分为四种授权模式,解决不同场景下的授权需求
| 授权模式 | 简介 |
| :-------- | :-------- |
@@ -146,50 +165,34 @@ Sa-OAuth2 模块分为四种授权模式,解决不同场景下的授权需求
详细参考文档:[https://sa-token.cc/doc.html#/oauth2/readme](https://sa-token.cc/doc.html#/oauth2/readme)
## 使用 Sa-Token 的开源项目
### 开源集成案例
- [[ Snowy ]](https://gitee.com/xiaonuobase/snowy):国内首个国密前后分离快速开发平台,采用 Vue3 + AntDesignVue3 + Vite + SpringBoot + Mp + HuTool + SaToken。
- [[ RuoYi-Vue-Plus ]](https://gitee.com/dromara/RuoYi-Vue-Plus)重写RuoYi-Vue所有功能 集成 Sa-Token+Mybatis-Plus+Jackson+Xxl-Job+knife4j+Hutool+OSS 定期同步
- [[ RuoYi-Cloud-Plus ]](https://gitee.com/dromara/RuoYi-Cloud-Plus)重写RuoYi-Cloud所有功能 整合 SpringCloudAlibaba Dubbo3.0 Sa-Token Mybatis-Plus MQ OSS ES Xxl-Job Docker 全方位升级 定期同步
- [[ EasyAdmin ]](https://gitee.com/lakernote/easy-admin)一个基于SpringBoot2 + Sa-Token + Mybatis-Plus + Snakerflow + Layui 的后台管理系统,灵活多变可前后端分离,也可单体,内置代码生成器、权限管理、工作流引擎等
- [[ YC-Framework ]](http://framework.youcongtech.com/):致力于打造一款优秀的分布式微服务解决方案。
- [[ Pig-Satoken ]](https://gitee.com/wchenyang/cloud-satoken):重写 Pig 授权方式为 Sa-Token其他代码不变。
更多开源案例可参考:[Awesome-Sa-Token](https://gitee.com/sa-token/awesome-sa-token)
还有更多优秀开源案例无法逐一展示,请参考:[Awesome-Sa-Token](https://gitee.com/sa-token/awesome-sa-token)
## 友情链接
### 友情链接
- [[ OkHttps ]](https://gitee.com/ejlchina-zhxu/okhttps):轻量级 http 通信框架API无比优雅支持 WebSocket、Stomp 协议
- [[ Bean Searcher ]](https://github.com/ejlchina/bean-searcher):专注高级查询的只读 ORM使一行代码实现复杂列表检索
- [[ Jpom ]](https://gitee.com/dromara/Jpom):简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件。
- [[ TLog ]](https://gitee.com/dromara/TLog):一个轻量级的分布式日志标记追踪神器。
- [[ hippo4j ]](https://gitee.com/agentart/hippo4j):强大的动态线程池框架,附带监控报警功能。
- [[ hertzbeat ]](https://gitee.com/dromara/hertzbeat)易用友好的开源实时监控告警系统无需Agent高性能集群强大自定义监控能力。
- [[ Solon ]](https://gitee.com/noear/solon):一个更现代感的应用开发框架:更快、更小、更自由。
## 知识星球
<img src="https://oss.dev33.cn/sa-token/dromara-xingqiu--sa-token.jpg" width="300px" />
## 交流群
### 交流群
QQ交流群685792424 [点击加入](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Y05Ld4125W92YSwZ0gA8e3RhG9Q4Vsfx&authKey=IomXuIuhP9g8G7l%2ByfkrRsS7i%2Fna0lIBpkTXxx%2BQEaz0NNEyJq00kgeiC4dUyNLS&noverify=0&group_code=685792424)
微信交流群:
<img src="https://oss.dev33.cn/sa-token/qr/wx-qr-m-400k.png" width="230px" title="微信群" />
<!-- ![微信群](https://dev33-test.oss-cn-beijing.aliyuncs.com/sa-token/i-wx-qr.png ':size=230') -->
(扫码添加微信备注sa-token邀您加入群聊)

View File

@@ -2,38 +2,55 @@
:: 整体clean
call mvn clean
:: demo模块clean
cd sa-token-demo
cd sa-token-demo-alone-redis & call mvn clean & cd ..
cd sa-token-demo-alone-redis-cluster & call mvn clean & cd ..
cd sa-token-demo-beetl & call mvn clean & cd ..
cd sa-token-demo-bom-import & call mvn clean & cd ..
cd sa-token-demo-case & call mvn clean & cd ..
cd sa-token-demo-grpc & call mvn clean & cd ..
cd sa-token-demo-hutool-timed-cache & call mvn clean & cd ..
cd sa-token-demo-jwt & call mvn clean & cd ..
cd sa-token-demo-quick-login & call mvn clean & cd ..
cd sa-token-demo-solon & call mvn clean & cd ..
cd sa-token-demo-solon-redisson & call mvn clean & cd ..
cd sa-token-demo-springboot & call mvn clean & cd ..
cd sa-token-demo-springboot3-redis & call mvn clean & cd ..
cd sa-token-demo-springboot-redis & call mvn clean & cd ..
cd sa-token-demo-springboot-redisson & call mvn clean & cd ..
cd sa-token-demo-ssm & call mvn clean & cd ..
cd sa-token-demo-test & call mvn clean & cd ..
cd sa-token-demo-thymeleaf & call mvn clean & cd ..
cd sa-token-demo-beetl & call mvn clean & cd ..
cd sa-token-demo-webflux & call mvn clean & cd ..
cd sa-token-demo-webflux-springboot3 & call mvn clean & cd ..
cd sa-token-demo-websocket & call mvn clean & cd ..
cd sa-token-demo-websocket-spring & call mvn clean & cd ..
cd sa-token-demo-bom-import & call mvn clean & cd ..
cd sa-token-demo-hutool-timed-cache & call mvn clean & cd ..
cd sa-token-demo-dubbo
cd sa-token-demo-dubbo-consumer & call mvn clean & cd ..
cd sa-token-demo-dubbo-provider & call mvn clean & cd ..
cd sa-token-demo-dubbo3-consumer & call mvn clean & cd ..
cd sa-token-demo-dubbo3-provider & call mvn clean & cd ..
cd ..
cd sa-token-demo-oauth2
cd sa-token-demo-oauth2-client & call mvn clean & cd ..
cd sa-token-demo-oauth2-server & call mvn clean & cd ..
cd ..
cd sa-token-demo-remember-me
cd sa-token-demo-remember-me-server & call mvn clean & cd ..
cd ..
cd sa-token-demo-sso
cd sa-token-demo-sso-server & call mvn clean & cd ..
cd sa-token-demo-sso1-client & call mvn clean & cd ..
cd sa-token-demo-sso2-client & call mvn clean & cd ..
cd sa-token-demo-sso3-client & call mvn clean & cd ..
cd sa-token-demo-sso3-client-test2 & call mvn clean & cd ..
cd sa-token-demo-sso3-client-nosdk & call mvn clean & cd ..
cd ..
@@ -44,31 +61,6 @@ cd sa-token-demo-sso3-client-solon & call mvn clean & cd ..
cd sa-token-demo-sso-server-solon & call mvn clean & cd ..
cd ..
cd sa-token-demo-oauth2
cd sa-token-demo-oauth2-client & call mvn clean & cd ..
cd sa-token-demo-oauth2-server & call mvn clean & cd ..
cd ..
:: cd sa-token-demo-cross
:: cd sa-token-demo-cross-header-server & call mvn clean & cd ..
:: cd sa-token-demo-cross-cookie-server & call mvn clean & cd ..
:: cd ..
cd sa-token-demo-dubbo
cd sa-token-demo-dubbo-consumer & call mvn clean & cd ..
cd sa-token-demo-dubbo-provider & call mvn clean & cd ..
cd sa-token-demo-dubbo3-consumer & call mvn clean & cd ..
cd sa-token-demo-dubbo3-provider & call mvn clean & cd ..
cd ..
cd sa-token-demo-remember-me
cd sa-token-demo-remember-me-server & call mvn clean & cd ..
cd ..
cd ..

View File

@@ -37,7 +37,7 @@
<!-- 一些属性 -->
<properties>
<revision>1.37.0</revision>
<revision>1.38.0</revision>
<jdk.version>1.8</jdk.version>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>utf-8</project.reporting.outputEncoding>

View File

@@ -13,7 +13,7 @@
<url>https://github.com/dromara/sa-token</url>
<properties>
<revision>1.37.0</revision>
<revision>1.38.0</revision>
</properties>
<dependencyManagement>
@@ -99,6 +99,11 @@
<artifactId>sa-token-dubbo</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dubbo3</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-grpc</artifactId>
@@ -139,6 +144,11 @@
<artifactId>sa-token-redisx</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-hutool-timed-cache</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dialect-thymeleaf</artifactId>

View File

@@ -61,11 +61,18 @@ public @interface SaCheckOr {
SaCheckSafe[] safe() default {};
/**
* 设定 @SaCheckBasic参考 {@link SaCheckHttpBasic}
* 设定 @SaCheckHttpBasic参考 {@link SaCheckHttpBasic}
*
* @return /
*/
SaCheckHttpBasic[] basic() default {};
SaCheckHttpBasic[] httpBasic() default {};
/**
* 设定 @SaCheckBasic参考 {@link SaCheckHttpDigest}
*
* @return /
*/
SaCheckHttpDigest[] httpDigest() default {};
/**
* 设定 @SaCheckDisable参考 {@link SaCheckDisable}

View File

@@ -37,6 +37,17 @@ public class SaSignConfig {
private long timestampDisparity = 1000 * 60 * 15;
public SaSignConfig() {
}
/**
* 构造函数
* @param secretKey 秘钥
*/
public SaSignConfig(String secretKey) {
this.secretKey = secretKey;
}
/**
* 获取 API 调用签名秘钥
*

View File

@@ -125,6 +125,9 @@ public interface SaErrorCode {
/** 获取 SaSession 时提供的 SessionId 为空 */
int CODE_11072 = 11072;
/** 获取 Token-Session 时提供的 token 为空 */
int CODE_11073 = 11073;
// ------------

View File

@@ -26,6 +26,8 @@ import cn.dev33.satoken.util.SaFoxUtil;
import java.util.Map;
import java.util.TreeMap;
import static cn.dev33.satoken.SaManager.log;
/**
* API 参数签名算法,在跨系统接口调用时防参数篡改、防重放攻击。
*
@@ -42,6 +44,17 @@ import java.util.TreeMap;
*/
public class SaSignTemplate {
public SaSignTemplate() {
}
/**
* 构造函数
* @param signConfig 签名参数配置对象
*/
public SaSignTemplate(SaSignConfig signConfig) {
this.signConfig = signConfig;
}
// ----------- 签名配置
SaSignConfig signConfig;
@@ -160,7 +173,14 @@ public class SaSignTemplate {
// 计算签名
String paramsStr = joinParamsDictSort(paramsMap);
String fullStr = paramsStr + "&" + key + "=" + secretKey;
return abstractStr(fullStr);
String signStr = abstractStr(fullStr);
// 输入日志,方便调试
log.debug("fullStr{}", fullStr);
log.debug("signStr{}", signStr);
// 返回
return signStr;
}
/**

View File

@@ -334,15 +334,15 @@ public class StpLogic {
tokenValue = String.valueOf(storage.get(splicingKeyJustCreatedSave()));
}
// 2. 再尝试从 请求体 里面读取
if(tokenValue == null && config.getIsReadBody()){
if(SaFoxUtil.isEmpty(tokenValue) && config.getIsReadBody()){
tokenValue = request.getParam(keyTokenName);
}
// 3. 再尝试从 header 头里读取
if(tokenValue == null && config.getIsReadHeader()){
if(SaFoxUtil.isEmpty(tokenValue) && config.getIsReadHeader()){
tokenValue = request.getHeader(keyTokenName);
}
// 4. 最后尝试从 cookie 里读取
if(tokenValue == null && config.getIsReadCookie()){
if(SaFoxUtil.isEmpty(tokenValue) && config.getIsReadCookie()){
tokenValue = request.getCookieValue(keyTokenName);
}
@@ -994,12 +994,12 @@ public class StpLogic {
if(loginId == null) {
return defaultValue;
}
// 3、loginId 不为 null则开始尝试类型转换
if (defaultValue == null) {
return null;
}
// 3、loginId 不为 null则开始尝试类型转换
if(defaultValue == null) {
return (T) loginId;
}
return (T) SaFoxUtil.getValueByType(loginId, defaultValue.getClass());
}
}
/**
* 获取当前会话账号id, 如果未登录则返回null
@@ -1198,6 +1198,9 @@ public class StpLogic {
// 如果是 Token-Session则使用对用 token 的有效期,使 token 和 token-session 保持相同ttl同步失效
if(SaTokenConsts.SESSION_TYPE__TOKEN.equals(session.getType())) {
timeout = getTokenTimeout(session.getToken());
if(timeout == SaTokenDao.NOT_VALUE_EXPIRE) {
timeout = getConfigOrGlobal().getTimeout();
}
} else {
// 否则使用全局配置的 timeout
timeout = getConfigOrGlobal().getTimeout();
@@ -1293,9 +1296,8 @@ public class StpLogic {
*/
public SaSession getTokenSessionByToken(String tokenValue, boolean isCreate) {
if(SaFoxUtil.isEmpty(tokenValue)) {
throw new SaTokenException("Token-Session 获取失败token 不能为空");
throw new SaTokenException("Token-Session 获取失败token 为空").setCode(SaErrorCode.CODE_11073);
}
// todo 待优化
return getSessionBySessionId(splicingKeyTokenSession(tokenValue), isCreate, null, session -> {
// 这里是该 Token-Session 首次创建时才会被执行的方法:
// 设定这个 SaSession 的各种基础信息类型、账号体系、Token 值
@@ -1331,7 +1333,7 @@ public class StpLogic {
// 2、如果前端根本没有提供 Token ,则直接返回 null
String tokenValue = getTokenValue();
if(SaFoxUtil.isEmpty(tokenValue)) {
return null;
throw new SaTokenException("Token-Session 获取失败token 为空").setCode(SaErrorCode.CODE_11073);
}
// 3、代码至此tokenSessionCheckLogin 校验通过、且 Token 有值
@@ -1408,7 +1410,14 @@ public class StpLogic {
setTokenValue(tokenValue);
// 返回其 Token-Session 对象
return getTokenSessionByToken(tokenValue, isCreate);
final String finalTokenValue = tokenValue;
return getSessionBySessionId(splicingKeyTokenSession(tokenValue), isCreate, getConfigOrGlobal().getTimeout(), session -> {
// 这里是该 Anon-Token-Session 首次创建时才会被执行的方法:
// 设定这个 SaSession 的各种基础信息类型、账号体系、Token 值
session.setType(SaTokenConsts.SESSION_TYPE__TOKEN);
session.setLoginType(getLoginType());
session.setToken(finalTokenValue);
});
}
else {
return null;
@@ -2672,7 +2681,13 @@ public class StpLogic {
return false;
}
// 2、如果缓存中可以查询出指定的键值,则代表已认证,否则视为未认证
// 2、如果此 token 不处于登录状态,也将其视为未认证
Object loginId = getLoginIdNotHandle(tokenValue);
if( ! isValidLoginId(loginId) ) {
return false;
}
// 3、如果缓存中可以查询出指定的键值则代表已认证否则视为未认证
String value = getSaTokenDao().get(splicingKeySafe(tokenValue, service));
return !(SaFoxUtil.isEmpty(value));
}
@@ -2690,8 +2705,14 @@ public class StpLogic {
* @param service 业务标识
*/
public void checkSafe(String service) {
// 1、必须先通过登录校验
checkLogin();
// 2、再进行二级认证校验
// 如果缓存中可以查询出指定的键值,则代表已认证,否则视为未认证
String tokenValue = getTokenValue();
if ( ! isSafe(tokenValue, service)) {
String value = getSaTokenDao().get(splicingKeySafe(tokenValue, service));
if(SaFoxUtil.isEmpty(value)) {
throw new NotSafeException(loginType, tokenValue, service).setCode(SaErrorCode.CODE_11071);
}
}

View File

@@ -17,10 +17,10 @@ package cn.dev33.satoken.strategy;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
import cn.dev33.satoken.exception.RequestPathInvalidException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.fun.strategy.*;
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
import cn.dev33.satoken.httpauth.digest.SaHttpDigestUtil;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpLogic;
@@ -265,8 +265,8 @@ public final class SaStrategy {
}
// 6、校验注解@SaCheckBasic
SaCheckHttpBasic[] checkBasicArray = at.basic();
for (SaCheckHttpBasic item : checkBasicArray) {
SaCheckHttpBasic[] checkHttpBasicArray = at.httpBasic();
for (SaCheckHttpBasic item : checkHttpBasicArray) {
try {
SaHttpBasicUtil.check(item.realm(), item.account());
return;
@@ -275,6 +275,17 @@ public final class SaStrategy {
}
}
// 7、校验注解@SaCheckDigest
SaCheckHttpDigest[] checkHttpDigestArray = at.httpDigest();
for (SaCheckHttpDigest item : checkHttpDigestArray) {
try {
SaHttpDigestUtil.checkByAnnotation(item);
return;
} catch (SaTokenException e) {
errorList.add(e);
}
}
// 如果执行到这里,有两种可能:
// 可能 1. SaCheckOr 注解上不包含任何注解校验,此时 errorList 里面一个异常都没有,我们直接跳过即可
// 可能 2. 所有注解校验都通过不了,此时 errorList 里面会有多个异常,我们随便抛出一个即可

View File

@@ -36,7 +36,7 @@ public class SaTokenConsts {
/**
* Sa-Token 当前版本号
*/
public static final String VERSION_NO = "v1.37.0";
public static final String VERSION_NO = "v1.38.0";
/**
* Sa-Token 开源地址 Gitee

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>
@@ -73,7 +73,7 @@
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-bom</artifactId>
<version>1.37.0</version>
<version>1.38.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -1,12 +1,5 @@
package com.pj.satoken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
@@ -14,6 +7,13 @@ import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.util.SaResult;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.PostConstruct;
/**
@@ -114,11 +114,11 @@ public class SaTokenConfigure implements WebMvcConfigurer {
/**
* 重写 Sa-Token 框架内部算法策略
*/
@Autowired
@PostConstruct
public void rewriteSaStrategy() {
// 重写Sa-Token的注解处理器增加注解合并功能
SaStrategy.instance.getAnnotation = (element, annotationClass) -> {
return AnnotatedElementUtils.getMergedAnnotation(element, annotationClass);
return AnnotatedElementUtils.getMergedAnnotation(element, annotationClass);
};
}

View File

@@ -4,18 +4,21 @@ import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* Sa-Token 权限认证工具类 (User 版)
* Sa-Token 权限认证工具类User版)
*
* @author click33
* @since 1.0.0
*/
@Component
public class StpUserUtil {
private StpUserUtil() {}
@@ -302,6 +305,15 @@ public class StpUserUtil {
return stpLogic.isLogin();
}
/**
* 判断指定账号是否已经登录
*
* @return 已登录返回 true未登录返回 false
*/
public static boolean isLogin(Object loginId) {
return stpLogic.isLogin(loginId);
}
/**
* 检验当前会话是否已经登录,如未登录,则抛出异常
*/
@@ -802,6 +814,17 @@ public class StpUserUtil {
return stpLogic.getTokenValueListByLoginId(loginId, device);
}
/**
* 获取指定账号 id 指定设备类型端的 tokenSign 集合
*
* @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 tokenSign
*/
public static List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) {
return stpLogic.getTokenSignListByLoginId(loginId, device);
}
/**
* 返回当前会话的登录设备类型
*
@@ -811,6 +834,26 @@ public class StpUserUtil {
return stpLogic.getLoginDevice();
}
/**
* 返回指定 token 会话的登录设备类型
*
* @param tokenValue 指定token
* @return 当前令牌的登录设备类型
*/
public static String getLoginDeviceByToken(String tokenValue) {
return stpLogic.getLoginDeviceByToken(tokenValue);
}
/**
* 获取当前 token 的最后活跃时间13位时间戳如果不存在则返回 -2
*
* @return /
*/
public static long getTokenLastActiveTime() {
return stpLogic.getTokenLastActiveTime();
}
// ------------------- 会话管理 -------------------

View File

@@ -17,7 +17,7 @@
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<dubbo.version>2.7.21</dubbo.version>
<nacos.version>1.4.2</nacos.version>
</properties>

View File

@@ -17,7 +17,7 @@
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<dubbo.version>2.7.21</dubbo.version>
<nacos.version>1.4.2</nacos.version>
</properties>

View File

@@ -17,7 +17,7 @@
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<dubbo.version>3.2.2</dubbo.version>
<nacos.version>2.2.2</nacos.version>
</properties>

View File

@@ -17,7 +17,7 @@
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<dubbo.version>3.2.2</dubbo.version>
<nacos.version>2.2.2</nacos.version>
</properties>

View File

@@ -27,7 +27,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lombok.version>1.18.10</lombok.version>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<!-- 定义 Sa-Token 版本号 -->
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<!-- 定义 Sa-Token 版本号 -->
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
</parent>
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -10,13 +10,13 @@
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.4.0</version>
<version>2.7.0</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

View File

@@ -10,13 +10,13 @@
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.4.0</version>
<version>2.7.0</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
@@ -40,7 +40,7 @@
<artifactId>sa-token-solon-plugin</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- sa-token整合redis (使用jdk默认序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>

View File

@@ -1,15 +1,14 @@
package com.pj.satoken;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoOfRedis;
import cn.dev33.satoken.dao.SaTokenDaoOfRedisJson;
import cn.dev33.satoken.solon.integration.SaTokenInterceptor;
import com.pj.util.AjaxJson;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import com.pj.util.AjaxJson;
import cn.dev33.satoken.context.SaHolder;
import org.noear.solon.annotation.Inject;
@@ -59,9 +58,11 @@ public class SaTokenConfigure {
;
});
}
//如果需要 redis dao加这段代表
// @Bean
// public SaTokenDao saTokenDaoInit(@Inject("${sa-token-dao.redis}") SaTokenDaoOfRedis saTokenDao) {
// return saTokenDao;
// }
//如果需要 redis dao加这段代表
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token-dao.redis}") SaTokenDaoOfRedisJson saTokenDao) {
return saTokenDao;
}
}

View File

@@ -23,7 +23,7 @@ sa-token:
sa-token-dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
# password: 123456
db: 1
maxTotal: 200

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -27,7 +27,7 @@
<!--<spring.version>4.2.5.RELEASE</spring.version>-->
<spring.version>5.3.7</spring.version>
<jackson.version>2.16.1</jackson.version>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -10,14 +10,14 @@
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.4.0</version>
<version>2.7.0</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<solon.version>2.2.3</solon.version>
<sa-token.version>1.38.0</sa-token.version>
<solon.version>2.7.0</solon.version>
</properties>
<dependencies>
@@ -49,7 +49,7 @@
<artifactId>sa-token-redisx</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- 视图引擎(在前后端不分离模式下提供视图支持) -->
<dependency>
<groupId>org.noear</groupId>

View File

@@ -1,6 +1,7 @@
package com.pj;
import cn.dev33.satoken.sso.SaSsoManager;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
@@ -9,7 +10,13 @@ public class SaSsoServerApp {
public static void main(String[] args) {
Solon.start(SaSsoServerApp.class, args);
System.out.println("\n------ Sa-Token-SSO 统一认证中心启动成功 ");
System.out.println();
System.out.println("---------------------- Solon Sa-Token SSO 统一认证中心启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getServerConfig());
System.out.println("统一认证登录地址http://sa-sso-server.com:9000/sso/auth");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -21,7 +21,7 @@ public class SsoConfig {
* 构建建 SaToken redis dao如果不需要 redis可以注释掉
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.redis}") SaTokenDaoOfRedis saTokenDao) {
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
@@ -44,12 +44,13 @@ public class SsoConfig {
return SaResult.error("登录失败!");
};
// 配置 Http 请求处理器 (在模式三的单点注销功能下用到,如不需要可以注释掉)
// 配置 Http 请求处理器
ssoServer.sendHttp = url -> {
try {
// 发起 http 请求
System.out.println("------ 发起请求:" + url);
return Forest.get(url).executeAsString();
String resStr = Forest.get(url).executeAsString();
System.out.println("------ 请求结果:" + resStr);
return resStr;
} catch (Exception e) {
e.printStackTrace();
return null;

View File

@@ -26,10 +26,10 @@ sa-token:
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# ---- 除了以上配置项,你还需要为 Sa-Token 配置http请求处理器文档有步骤说明
sa-token: #名字可以随意取
sa-token.dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
# password: 123456
db: 1
maxTotal: 200

View File

@@ -10,13 +10,13 @@
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.4.0</version>
<version>2.7.0</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@ public class SaConfig {
* 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.redis}") SaTokenDaoOfRedis saTokenDao) {
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
}

View File

@@ -1,6 +1,7 @@
package com.pj;
import cn.dev33.satoken.sso.SaSsoManager;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
@@ -15,6 +16,15 @@ public class SaSso1ClientApp {
public static void main(String[] args) {
Solon.start(SaSso1ClientApp.class, args);
System.out.println("\nSa-Token SSO模式一 Client端启动成功");
System.out.println();
System.out.println("---------------------- Solon Sa-Token SSO 模式一 Client 端启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
System.out.println("测试访问应用端一: http://s1.stp.com:9001");
System.out.println("测试访问应用端二: http://s2.stp.com:9001");
System.out.println("测试访问应用端三: http://s3.stp.com:9001");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -6,16 +6,14 @@ server:
sa-token:
# SSO-相关配置
sso-client:
# SSO-Server端-单点登录授权地址
auth-url: http://sso.stp.com:9000/sso/auth
# SSO-Server端-单点注销地址
slo-url: http://sso.stp.com:9000/sso/signout
# SSO-Server端 - 主机地址
server-url: http://sso.stp.com:9000
# 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
sa-token: #名字可以随意取
sa-token.dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
# password: 123456
db: 1
maxTotal: 200

View File

@@ -10,13 +10,13 @@
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.4.0</version>
<version>2.7.0</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>
@@ -47,6 +47,13 @@
<artifactId>sa-token-redisx</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Http 请求工具 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>forest-solon-plugin</artifactId>
</dependency>
</dependencies>

View File

@@ -2,8 +2,11 @@ package com.pj;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoOfRedis;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import com.dtflys.forest.Forest;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Init;
import org.noear.solon.annotation.Inject;
/**
@@ -16,7 +19,19 @@ public class SaConfig {
* 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.redis}") SaTokenDaoOfRedis saTokenDao) {
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
@Bean
public void configSso(SaSsoClientConfig ssoClient) {
// 配置Http请求处理器
ssoClient.sendHttp = url -> {
System.out.println("------ 发起请求:" + url);
String resStr = Forest.get(url).executeAsString();
System.out.println("------ 请求结果:" + resStr);
return resStr;
};
}
}

View File

@@ -1,6 +1,7 @@
package com.pj;
import cn.dev33.satoken.sso.SaSsoManager;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
@@ -9,7 +10,15 @@ public class SaSso2ClientApp {
public static void main(String[] args) {
Solon.start(SaSso2ClientApp.class, args);
System.out.println("\nSa-Token SSO模式二 Client端启动成功");
System.out.println();
System.out.println("---------------------- Solon Sa-Token SSO 模式二 Client 端启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9002");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9002");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9002");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -34,7 +34,7 @@ public class H5Controller implements Render {
// 根据ticket进行登录
@Mapping("/sso/doLoginByTicket")
public SaResult doLoginByTicket(String ticket) {
Object loginId = SaSsoClientProcessor.instance.checkTicketByMode2Or3(ticket, "/sso/doLoginByTicket");
Object loginId = SaSsoClientProcessor.instance.checkTicket(ticket, "/sso/doLoginByTicket");
if(loginId != null) {
StpUtil.login(loginId);
return SaResult.data(StpUtil.getTokenValue());

View File

@@ -1,22 +1,25 @@
# 端口
server:
port: 9001
port: 9002
# sa-token配置
sa-token:
# SSO-相关配置
sso-client:
# SSO-Server端 统一认证地址
auth-url: http://sa-sso-server.com:9000/sso/auth
# SSO-Server端 主机地址
server-url: http://sa-sso-server.com:9000
# auth-url: http://127.0.0.1:8848/sa-token-demo-sso-server-h5/sso-auth.html
# 是否打开单点注销接口
is-slo: true
sign:
# API 接口调用秘钥
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
sa-token: #名字可以随意取
sa-token.dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
# password: 123456
db: 1
maxTotal: 200

View File

@@ -10,13 +10,13 @@
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.4.0</version>
<version>2.7.0</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>
@@ -26,6 +26,12 @@
<groupId>org.noear</groupId>
<artifactId>solon-api</artifactId>
</dependency>
<!-- Http 请求工具 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>forest-solon-plugin</artifactId>
</dependency>
<!-- Sa-Token 权限认证, 在线文档https://sa-token.cc/ -->
<dependency>
@@ -47,15 +53,7 @@
<artifactId>sa-token-redisx</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Http 请求工具 -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-solon-plugin</artifactId>
<version>1.5.29</version>
</dependency>
</dependencies>

View File

@@ -16,7 +16,7 @@ public class SaConfig {
* 构建建 SaToken redis dao如果不需要 redis可以注释掉
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.redis}") SaTokenDaoOfRedis saTokenDao) {
public SaTokenDao saTokenDaoInit(@Inject("${sa-token.dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
}

View File

@@ -1,5 +1,6 @@
package com.pj;
import cn.dev33.satoken.sso.SaSsoManager;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
@@ -8,7 +9,15 @@ public class SaSso3ClientApp {
public static void main(String[] args) {
Solon.start(SaSso3ClientApp.class, args);
System.out.println("\nSa-Token SSO模式三 Client端启动成功");
System.out.println();
System.out.println("---------------------- Solon Sa-Token SSO 模式三 Client 端启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9003");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9003");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9003");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -1,50 +0,0 @@
package com.pj.sso;
import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
import cn.dev33.satoken.sso.template.SaSsoClientTemplate;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* solon 的 sso 适配,在 cn.dev33:sa-token-solon-plugin:1.34.0 里还没有。(临时加这个类)
*
* //todo: 如果使用 org.noear:sa-token-solon-plugin:xxx ,则需要删掉这个类
*
* @author noear
* @since 2.0
*/
@Condition(onClass = SaSsoManager.class)
@Configuration
public class SaSsoAutoConfigure {
/**
* 获取 SSO 配置Bean
* */
@Bean
public SaSsoClientConfig getConfig(@Inject(value = "${sa-token.sso-client}",required = false) SaSsoClientConfig ssoConfig) {
return ssoConfig;
}
/**
* 注入 Sa-Token-SSO 配置Bean
*
* @param saSsoConfig 配置对象
*/
@Bean
public void setSaSsoConfig(@Inject(required = false) SaSsoClientConfig saSsoConfig) {
SaSsoManager.setClientConfig(saSsoConfig);
}
/**
* 注入 Sa-Token-SSO 单点登录模块 Bean
*
* @param ssoClientTemplate ssoClientTemplate对象
*/
@Bean
public void setSaSsoClientTemplate(@Inject(required = false) SaSsoClientTemplate ssoClientTemplate) {
SaSsoClientProcessor.instance.ssoClientTemplate = ssoClientTemplate;
}
}

View File

@@ -16,7 +16,9 @@ public class SsoConfig {
// 配置Http请求处理器
ssoClient.sendHttp = url -> {
System.out.println("------ 发起请求:" + url);
return Forest.get(url).executeAsString();
String resStr = Forest.get(url).executeAsString();
System.out.println("------ 请求结果:" + resStr);
return resStr;
};
}
}

View File

@@ -1,32 +1,27 @@
# 端口
server:
port: 9001
port: 9003
# sa-token配置
sa-token:
# SSO-相关配置
sso-client:
# SSO-Server端 统一认证地址
auth-url: http://sa-sso-server.com:9000/sso/auth
# SSO-Server端 主机地址
server-url: http://sa-sso-server.com:9000
# 使用Http请求校验ticket
is-http: true
# SSO-Server端 ticket校验地址
check-ticket-url: http://sa-sso-server.com:9000/sso/checkTicket
# 打开单点注销功能
is-slo: true
# 单点注销地址
slo-url: http://sa-sso-server.com:9000/sso/signout
sign:
# 接口调用秘钥
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# SSO-Server端 查询userinfo地址
userinfo-url: http://sa-sso-server.com:9000/sso/userinfo
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# 配置 Sa-Token Dao此处与SSO-Server端连接不同的Redis
sa-token: #名字可以随意取
sa-token.dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
# password: 123456
db: 2
maxTotal: 200

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -1,5 +1,6 @@
package com.pj;
import cn.dev33.satoken.sso.SaSsoManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -8,7 +9,13 @@ public class SaSsoServerApplication {
public static void main(String[] args) {
SpringApplication.run(SaSsoServerApplication.class, args);
System.out.println("\n------ Sa-Token-SSO 统一认证中心启动成功 ");
System.out.println();
System.out.println("---------------------- Sa-Token SSO 统一认证中心启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getServerConfig());
System.out.println("统一认证登录地址http://sa-sso-server.com:9000/sso/auth");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -25,7 +25,7 @@ public class SsoServerController {
* http://{host}:{port}/sso/auth -- 单点登录授权地址接受参数redirect=授权重定向地址
* http://{host}:{port}/sso/doLogin -- 账号密码登录接口接受参数name、pwd
* http://{host}:{port}/sso/checkTicket -- Ticket校验接口isHttp=true时打开接受参数ticket=ticket码、ssoLogoutCall=单点注销回调地址 [可选]
* http://{host}:{port}/sso/signout -- 单点注销地址isSlo=true时打开接受参数loginId=账号id、secretkey=接口调用秘钥
* http://{host}:{port}/sso/signout -- 单点注销地址isSlo=true时打开接受参数loginId=账号id、sign=参数签名
*/
@RequestMapping("/sso/*")
public Object ssoRequest() {

View File

@@ -3,7 +3,7 @@ server:
port: 9000
# Sa-Token 配置
sa-token:
sa-token:
# ------- SSO-模式一相关配置 (非模式一不需要配置)
# cookie:
# 配置 Cookie 作用域

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>
@@ -60,7 +60,14 @@
<artifactId>sa-token-alone-redis</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Http请求工具 -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.26</version>
</dependency>
</dependencies>

View File

@@ -13,9 +13,9 @@ public class SaSso2ClientApplication {
System.out.println();
System.out.println("---------------------- Sa-Token SSO 模式二 Client 端启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9001");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9001");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9001");
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9002");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9002");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9002");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}

View File

@@ -33,7 +33,7 @@ public class H5Controller {
// 根据ticket进行登录
@RequestMapping("/sso/doLoginByTicket")
public SaResult doLoginByTicket(String ticket) {
Object loginId = SaSsoClientProcessor.instance.checkTicketByMode2Or3(ticket, "/sso/doLoginByTicket");
Object loginId = SaSsoClientProcessor.instance.checkTicket(ticket, "/sso/doLoginByTicket");
if(loginId != null) {
StpUtil.login(loginId);
return SaResult.data(StpUtil.getTokenValue());

View File

@@ -1,8 +1,11 @@
package com.pj.sso;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.dtflys.forest.Forest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -35,6 +38,18 @@ public class SsoClientController {
return SaSsoClientProcessor.instance.dister();
}
// 配置SSO相关参数
@Autowired
private void configSso(SaSsoClientConfig ssoClient) {
// 配置Http请求处理器
ssoClient.sendHttp = url -> {
System.out.println("------ 发起请求:" + url);
String resStr = Forest.get(url).executeAsString();
System.out.println("------ 请求结果:" + resStr);
return resStr;
};
}
// 全局异常拦截
@ExceptionHandler
public SaResult handlerException(Exception e) {

View File

@@ -1,15 +1,18 @@
# 端口
server:
port: 9001
port: 9002
# sa-token配置
sa-token:
sa-token:
# SSO-相关配置
sso-client:
# SSO-Server端 统一认证地址
# SSO-Server 端主机地址
server-url: http://sa-sso-server.com:9000
# 前后端分离时用这个
# auth-url: http://127.0.0.1:8848/sa-token-demo-sso-server-h5/sso-auth.html
sign:
# API 接口调用秘钥
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# 配置Sa-Token单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
alone-redis:
@@ -33,8 +36,7 @@ sa-token:
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
forest:
# 关闭 forest 请求日志打印
log-enabled: false

View File

@@ -1,14 +0,0 @@
package com.pj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SaSsoClientApplication {
public static void main(String[] args) {
SpringApplication.run(SaSsoClientApplication.class, args);
System.out.println("\nSa-Token SSO模式三 Client端 无SDK版本 启动成功");
}
}

View File

@@ -0,0 +1,22 @@
package com.pj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SaSsoClientNoSdkApplication {
public static void main(String[] args) {
SpringApplication.run(SaSsoClientNoSdkApplication.class, args);
System.out.println("\nSa-Token SSO模式三 Client端 无SDK版本 启动成功");
System.out.println();
System.out.println("---------------------- Sa-Token SSO 模式三 NoSdk 模式 demo 启动成功 ----------------------");
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9004");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9004");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9004");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -29,7 +29,7 @@ public class SsoClientController {
"<p>当前会话登录账号:" + session.getAttribute("userId") + "</p>" +
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a>" +
" <a href='/sso/logout?back=' + + encodeURIComponent(location.href);>注销</a>" +
" <a href='/sso/myinfo' target=\"_blank\">获取资料</a></p>";
" <a href='/sso/myInfo' target=\"_blank\">获取资料</a></p>";
return str;
}
@@ -62,8 +62,16 @@ public class SsoClientController {
ssoLogoutCall = request.getRequestURL().toString().replace("/sso/login", "/sso/logoutCall");
}
// 校验 ticket
String checkUrl = SsoRequestUtil.checkTicketUrl + "?ticket=" + ticket + "&ssoLogoutCall=" + ssoLogoutCall;
// 校验 ticket
String timestamp = String.valueOf(System.currentTimeMillis()); // 时间戳
String nonce = SsoRequestUtil.getRandomString(20); // 随机字符串
String sign = SsoRequestUtil.getSignByTicket(ticket, ssoLogoutCall, timestamp, nonce); // 参数签名
String checkUrl = SsoRequestUtil.checkTicketUrl +
"?timestamp=" + timestamp +
"&nonce=" + nonce +
"&sign=" + sign +
"&ticket=" + ticket +
"&ssoLogoutCall=" + ssoLogoutCall;
AjaxJson result = SsoRequestUtil.request(checkUrl);
// 200 代表校验成功
@@ -97,7 +105,7 @@ public class SsoClientController {
Object loginId = session.getAttribute("userId"); // 账号id
String timestamp = String.valueOf(System.currentTimeMillis()); // 时间戳
String nonce = SsoRequestUtil.getRandomString(20); // 随机字符串
String sign = SsoRequestUtil.getSign(loginId, timestamp, nonce, SsoRequestUtil.secretkey); // 参数签名
String sign = SsoRequestUtil.getSign(loginId, timestamp, nonce); // 参数签名
String url = SsoRequestUtil.sloUrl +
"?loginId=" + loginId +
@@ -123,12 +131,13 @@ public class SsoClientController {
// SSO-Client端单点注销回调地址
@RequestMapping("/sso/logoutCall")
public Object ssoLogoutCall(String loginId, String timestamp, String nonce, String sign) {
public Object ssoLogoutCall(String loginId, String autoLogout, String timestamp, String nonce, String sign) {
// 校验签名
String calcSign = SsoRequestUtil.getSign(loginId, timestamp, nonce, SsoRequestUtil.secretkey);
String calcSign = SsoRequestUtil.getSignByLogoutCall(loginId, autoLogout, timestamp, nonce);
if(calcSign.equals(sign) == false) {
return AjaxJson.getError("无效签名,拒绝应答");
System.out.println("无效签名,拒绝应答" + sign);
return AjaxJson.getError("无效签名,拒绝应答" + sign);
}
// 注销这个账号id
@@ -143,8 +152,8 @@ public class SsoClientController {
}
// 查询我的账号信息 (调用此接口的前提是 sso-server 端开放了 /sso/userinfo 路由)
@RequestMapping("/sso/myinfo")
public Object myinfo(HttpSession session) {
@RequestMapping("/sso/myInfo")
public Object myInfo(HttpSession session) {
// 如果尚未登录
if(session.getAttribute("userId") == null) {
return "尚未登录,无法获取";
@@ -154,9 +163,9 @@ public class SsoClientController {
Object loginId = session.getAttribute("userId"); // 账号id
String timestamp = String.valueOf(System.currentTimeMillis()); // 时间戳
String nonce = SsoRequestUtil.getRandomString(20); // 随机字符串
String sign = SsoRequestUtil.getSign(loginId, timestamp, nonce, SsoRequestUtil.secretkey); // 参数签名
String sign = SsoRequestUtil.getSign(loginId, timestamp, nonce); // 参数签名
String url = SsoRequestUtil.userinfoUrl +
String url = SsoRequestUtil.getDataUrl +
"?loginId=" + loginId +
"&timestamp=" + timestamp +
"&nonce=" + nonce +

View File

@@ -1,14 +1,14 @@
package com.pj.sso;
import com.dtflys.forest.Forest;
import com.pj.sso.util.AjaxJson;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Map;
import java.util.Random;
import com.dtflys.forest.Forest;
import com.pj.sso.util.AjaxJson;
/**
* 封装一些 sso 共用方法
*
@@ -17,40 +17,41 @@ import com.pj.sso.util.AjaxJson;
*/
public class SsoRequestUtil {
/**
* SSO-Server端主机地址
*/
public static String serverUrl = "http://sa-sso-server.com:9000";
/**
* SSO-Server端 统一认证地址
*/
public static String authUrl = "http://sa-sso-server.com:9000/sso/auth";
/**
* 使用 Http 请求校验ticket
*/
// public static boolean isHttp = true;
public static String authUrl = serverUrl + "/sso/auth";
/**
* SSO-Server端 ticket校验地址
*/
public static String checkTicketUrl = "http://sa-sso-server.com:9000/sso/checkTicket";
/**
* 打开单点注销功能
*/
public static boolean isSlo = true;
public static String checkTicketUrl = serverUrl + "/sso/checkTicket";
/**
* 单点注销地址
*/
public static String sloUrl = "http://sa-sso-server.com:9000/sso/signout";
public static String sloUrl = serverUrl + "/sso/signout";
/**
* SSO-Server端 查询userinfo地址
*/
public static String getDataUrl = serverUrl + "/sso/getData";
/**
* 打开单点注销功能
*/
public static boolean isSlo = true;
/**
* 接口调用秘钥
*/
public static String secretkey = "kQwIOrYvnXmSDkwEiFngrKidMcdrgKor";
/**
* SSO-Server端 查询userinfo地址
*/
public static String userinfoUrl = "http://sa-sso-server.com:9000/sso/userinfo";
public static String secretKey = "kQwIOrYvnXmSDkwEiFngrKidMcdrgKor";
// -------------------------- 工具方法
@@ -69,12 +70,19 @@ public class SsoRequestUtil {
* 根据参数计算签名
* @param loginId 账号id
* @param timestamp 当前时间戳13位
* @param nonce 随机字符串
* @param secretkey 账号id
* @param nonce 随机字符串
* @return 签名
*/
public static String getSign(Object loginId, String timestamp, String nonce, String secretkey) {
return md5("loginId=" + loginId + "&nonce=" + nonce + "&timestamp=" + timestamp + "&key=" + secretkey);
public static String getSign(Object loginId, String timestamp, String nonce) {
return md5("loginId=" + loginId + "&nonce=" + nonce + "&timestamp=" + timestamp + "&key=" + secretKey);
}
// 单点注销回调时构建签名
public static String getSignByLogoutCall(Object loginId, String autoLogout, String timestamp, String nonce) {
return md5("autoLogout=" + autoLogout + "&loginId=" + loginId + "&nonce=" + nonce + "&timestamp=" + timestamp + "&key=" + secretKey);
}
// 校验ticket 时构建签名
public static String getSignByTicket(String ticket, String ssoLogoutCall, String timestamp, String nonce) {
return md5("nonce=" + nonce + "&ssoLogoutCall=" + ssoLogoutCall + "&ticket=" + ticket + "&timestamp=" + timestamp + "&key=" + secretKey);
}
/**

View File

@@ -1,6 +1,6 @@
# 端口
server:
port: 9001
port: 9004
forest:
# 打开/关闭Forest请求日志默认为 true

View File

@@ -0,0 +1,12 @@
target/
node_modules/
bin/
.settings/
unpackage/
.classpath
.project
.idea/
.factorypath

View File

@@ -0,0 +1,68 @@
<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-sso3-client-test2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- SpringBoot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.14</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>
<!-- SpringBoot依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<!-- Sa-Token 插件整合SSO -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- 提供Redis连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Http请求工具 -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.26</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,23 @@
package com.pj;
import cn.dev33.satoken.sso.SaSsoManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SaSso3ClientTest2Application {
public static void main(String[] args) {
SpringApplication.run(SaSso3ClientTest2Application.class, args);
System.out.println();
System.out.println("---------------------- Sa-Token SSO 模式三 Client 端启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9032");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9032");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9032");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}
}

View File

@@ -0,0 +1,78 @@
package com.pj.sso;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
import cn.dev33.satoken.sso.template.SaSsoUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.dtflys.forest.Forest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* Sa-Token-SSO Client端 Controller
* @author click33
*/
@RestController
public class SsoClientController {
// SSO-Client端首页
@RequestMapping("/")
public String index() {
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a>" +
" <a href='/sso/logout?back=self'>注销</a></p>";
return str;
}
/*
* SSO-Client端处理所有SSO相关请求
* http://{host}:{port}/sso/login -- Client端登录地址接受参数back=登录后的跳转地址
* http://{host}:{port}/sso/logout -- Client端单点注销地址isSlo=true时打开接受参数back=注销后的跳转地址
* http://{host}:{port}/sso/logoutCall -- Client端单点注销回调地址isSlo=true时打开此接口为框架回调开发者无需关心
*/
@RequestMapping("/sso/*")
public Object ssoRequest() {
return SaSsoClientProcessor.instance.dister();
}
// 配置SSO相关参数
@Autowired
private void configSso(SaSsoClientConfig ssoClient) {
// 配置Http请求处理器
ssoClient.sendHttp = url -> {
System.out.println("------ 发起请求:" + url);
String resStr = Forest.get(url).executeAsString();
System.out.println("------ 请求结果:" + resStr);
return resStr;
};
}
// 查询我的账号信息
@RequestMapping("/sso/myInfo")
public Object myInfo() {
// 组织请求参数
Map<String, Object> map = new HashMap<>();
map.put("apiType", "userinfo");
map.put("loginId", StpUtil.getLoginId());
// 发起请求
Object resData = SaSsoUtil.getData(map);
System.out.println("sso-server 返回的信息:" + resData);
return resData;
}
// 全局异常拦截
@ExceptionHandler
public SaResult handlerException(Exception e) {
e.printStackTrace();
return SaResult.error(e.getMessage());
}
}

View File

@@ -0,0 +1,49 @@
# 端口
server:
port: 9032
# sa-token配置
sa-token:
# sso-client 相关配置
sso-client:
# client 标识
client: sso-client3-test2
# sso-server 端主机地址
server-url: http://sa-sso-server.com:9000
# 使用 Http 请求校验ticket (模式三)
is-http: true
sign:
# API 接口调用秘钥
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
spring:
# 配置 Redis 连接 此处与SSO-Server端连接不同的Redis
redis:
# Redis数据库索引
database: 4
# 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
forest:
# 关闭 forest 请求日志打印
log-enabled: false

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -13,9 +13,9 @@ public class SaSso3ClientApplication {
System.out.println();
System.out.println("---------------------- Sa-Token SSO 模式三 Client 端启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9001");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9001");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9001");
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9003");
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9003");
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9003");
System.out.println("测试前需要根据官网文档修改hosts文件测试账号密码sa / 123456");
System.out.println();
}

View File

@@ -1,11 +1,13 @@
# 端口
server:
port: 9001
port: 9003
# sa-token配置
sa-token:
sa-token:
# sso-client 相关配置
sso-client:
# client 标识
client: sso-client3
# sso-server 端主机地址
server-url: http://sa-sso-server.com:9000
# 使用 Http 请求校验ticket (模式三)
@@ -19,7 +21,7 @@ spring:
# 配置 Redis 连接 此处与SSO-Server端连接不同的Redis
redis:
# Redis数据库索引
database: 2
database: 3
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口

View File

@@ -18,7 +18,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
<java.run.main.class>com.pj.SaTokenApplication</java.run.main.class>
</properties>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -16,7 +16,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -1,12 +1,10 @@
package com.pj.satoken;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import com.pj.util.AjaxJson;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.pj.util.AjaxJson;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
/**
* [Sa-Token 权限认证] 配置类
* @author click33
@@ -33,6 +31,7 @@ public class SaTokenConfigure {
// 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数
.setError(e -> {
System.out.println("---------- sa全局异常 ");
e.printStackTrace();
return AjaxJson.getError(e.getMessage());
})
;

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -17,7 +17,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.37.0</sa-token.version>
<sa-token.version>1.38.0</sa-token.version>
</properties>
<dependencies>

View File

@@ -12,7 +12,7 @@
<description>Sa-Token Dependencies</description>
<properties>
<revision>1.37.0</revision>
<revision>1.38.0</revision>
<!-- 统一定义依赖版本号 -->
<springboot.version>2.5.15</springboot.version>

View File

@@ -1,7 +1,7 @@
<p align="center">
<img alt="logo" src="https://sa-token.cc/logo.png" width="150" height="150">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">Sa-Token v1.37.0</h1>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">Sa-Token v1.38.0</h1>
<h5 align="center">一个轻量级 Java 权限认证框架,让鉴权变得简单、优雅!</h5>
<p align="center" class="badge-box">
<a href="https://gitee.com/dromara/sa-token/stargazers"><img src="https://gitee.com/dromara/sa-token/badge/star.svg?theme=gvp"></a>

View File

@@ -29,7 +29,7 @@
- [账号封禁](/up/disable)
- [密码加密](/up/password-secure)
- [会话查询](/up/search-session)
- [Http Basic 认证](/up/basic-auth)
- [Http Basic/Digest 认证](/up/basic-auth)
- [全局侦听器](/up/global-listener)
- [全局过滤器](/up/global-filter)
- [多账号认证](/up/many-account)
@@ -41,12 +41,14 @@
- [SSO模式一 共享Cookie同步会话](/sso/sso-type1)
- [SSO模式二 URL重定向传播会话](/sso/sso-type2)
- [SSO模式三 Http请求获取会话](/sso/sso-type3)
- [SSO整合配置域名校验](/sso/sso-check-domain)
- [SSO整合定制化登录页面](/sso/sso-custom-login)
- [SSO整合自定义API路由](/sso/sso-custom-api)
- [SSO扩展前后端分离下的整合方案](/sso/sso-h5)
- [SSO扩展平台中心跳转模式](/sso/sso-home-jump)
- [SSO扩展常见问题总结](/sso/sso-questions)
- [配置域名校验](/sso/sso-check-domain)
- [定制化登录页面](/sso/sso-custom-login)
- [自定义API路由](/sso/sso-custom-api)
- [前后端分离下的整合方案](/sso/sso-h5)
- [平台中心跳转模式](/sso/sso-home-jump)
- [不同 Client 不同秘钥](/sso/sso-diff-key)
- [用户数据同步 / 迁移](/sso/user-data-sync)
- [常见问题总结](/sso/sso-questions)
- [Sa-Sso-Pro单点登录商业版](/sso/sso-pro)
- **OAuth2.0**
@@ -92,6 +94,7 @@
- [加入讨论群](/more/join-group)
- [赞助 Sa-Token](/more/sa-token-donate)
- [需求提交](/more/demand-commit)
- [问卷调查](/more/wenjuan)
- **附录**
- [常见问题排查](/more/common-questions)

View File

@@ -38,6 +38,8 @@ StpUtil.login(10001, new SaLoginModel()
.setToken("xxxx-xxxx-xxxx-xxxx") // 预定此次登录生成的Token
.setExtra("name", "zhangsan") // Token挂载的扩展参数 此方法只有在集成jwt插件时才会生效
.setIsWriteHeader(false) // 是否在登录后将 Token 写入到响应头
.setActiveTimeout(300) // 指定此次登录token的最低活跃频率, 单位:秒设置此参数需要在配置文件打开dynamicActiveTimeout=true
.setTokenSignTag("xxx") // 指定此次登录挂载在 TokenSign 上的 tag 值, 任意值
);
```
@@ -92,6 +94,7 @@ StpUtil.getSessionBySessionId("xxxx-xxxx-xxxx"); // 获取指定key的Session,
``` java
// Token 最低活跃频率
StpUtil.getTokenActiveTimeout(); // 获取当前 token 距离被冻结还剩多少时间 (单位: 秒)
StpUtil.getTokenLastActiveTime(); // 获取当前 token 最后活跃时间
StpUtil.checkActiveTimeout(); // 检查当前token 是否已经被冻结,如果是则抛出异常
StpUtil.updateLastActiveToNow(); // 续签当前token(将 [最后操作时间] 更新为当前时间戳)
@@ -139,6 +142,7 @@ StpUtil.getTokenValueByLoginId(10001, "PC"); // 获取指定账号id指定设
StpUtil.getTokenValueListByLoginId(10001); // 获取指定账号id的tokenValue集合
StpUtil.getTokenValueListByLoginId(10001, "APP"); // 获取指定账号id指定设备类型端的tokenValue 集合
StpUtil.getLoginDevice(); // 返回当前会话的登录设备类型
StpUtil.getLoginDeviceByToken(xxx); // // 返回任意 token 的登录设备类型
```

View File

@@ -18,7 +18,7 @@
<div class="logo-box">
<img src="logo.png" title="logo" />
<h1 class="logo-text">Sa-Token</h1>
<sub>v1.37.0</sub>
<sub>v1.38.0</sub>
</div>
</a>
</div>
@@ -28,6 +28,7 @@
</div>
<select class="select-version p-none" onchange="location.href=this.value">
<option value="doc.html">最新版</option>
<option value="v/v1.37.0/doc.html">v1.37.0</option>
<option value="v/v1.36.0/doc.html">v1.36.0</option>
<option value="v/v1.35.0/doc.html">v1.35.0</option>
<option value="v/v1.34.0/doc.html">v1.34.0</option>
@@ -122,7 +123,7 @@
<a href="#/fun/sa-token-test">在线考试</a>
<a href="#/fun/issue-template">在线提问</a>
<!-- <a href="https://wj.qq.com/s2/10852322/0d8b/" target="_blank">需求提交</a> -->
<a href="https://wj.qq.com/s2/8475114/2f6a/" target="_blank">问卷调查</a>
<a href="#/more/wenjuan">问卷调查</a>
</div>
</div>
</div>
@@ -164,10 +165,11 @@
</script>
<!-- -->
<script src="./static/docsify-plugin.js?v=6"></script>
<script src="./static/is-star-plugin.js?v=6"></script>
<script src="./static/docsify-plugin.js?v=7"></script>
<script src="./static/is-star-plugin.js?v=7"></script>
<script src="./static/is-fill-in-wj-plugin.js?v=7"></script>
<script>
var saTokenTopVersion = '1.37.0'; // Sa-Token最新版本
var saTokenTopVersion = '1.38.0'; // Sa-Token最新版本
var name = '<img style="width: 60px; height: 60px; vertical-align: middle;" src="logo.png" alt="logo" /> ';
name += '<b style="font-size: 28px; vertical-align: middle;">Sa-Token</b> <sub>v' + saTokenTopVersion + '</sub>';
window.$docsify = {
@@ -201,7 +203,7 @@
tabHeadings: true // 用标题+粗体来定制选项卡
},
// 自定义插件
plugins: [myDocsifyPlugin, window.isStarPlugin],
plugins: [myDocsifyPlugin, window.isStarPlugin, window.isFillInWjPlugin],
}
</script>
<script src="static/docsify.min.js"></script>
@@ -291,11 +293,12 @@
<p>1、如果你是使用 PC 端微信,请点此链接:<a href="https://work.weixin.qq.com/kfid/kfcdd45c432fee9655f" target="_blank">https://work.weixin.qq.com/kfid/kfcdd45c432fee9655f</a></p>
<p>2、如果你是使用手机端微信请扫码</p>
<p><img src="https://oss.dev33.cn/sa-token/sa-token-xiaozhushou.jpg" width="200px"></p>
<p>如果您的问题已解决,我们希望您能够花费一点时间将解决方案发布在:<a href="https://gitee.com/dromara/sa-token/issues/I9I9CY" target="_blank">踩坑记录征集</a>,帮助以后遇到同样问题的开发者快速排查,感激不尽!</p>
</div>
`;
layer.alert(str, {
title: '技术求助',
area: '550px',
area: '650px',
offset: '10%',
})
})
@@ -303,7 +306,7 @@
// 给个小提示
const index = layer.tips('框架技术支持,点此求助', '.help-tips', {
tips: [1, '#000'] ,//还可配置颜色
time: 5000,
// time: 5000,
});
// 改为 fixed 定位,否则它会随着滚动条移动,样式就跑偏了
$('#layui-layer' + index).css('position', 'fixed');
@@ -388,5 +391,42 @@
$('.zk-btn--1').show();
}
</script>
<!-- 赞助效果图展示 -->
<script>
function showSyzz(){
layer.photos({
photos: {
title: '',
id: new Date().getTime(),
start: 0,
data: [
{
pid: 1,
alt: 'gitee 开源项目推广,日增 star 74',
src: 'https://oss.dev33.cn/sa-token/more/syzz-xg-1.png',
},
{
pid: 2,
alt: 'gitee 开源项目推广,日增 star 247',
src: 'https://oss.dev33.cn/sa-token/more/syzz-xg-2.png',
},
{
pid: 3,
alt: '某互联网公司线下活动,报名邀请',
src: 'https://oss.dev33.cn/sa-token/more/syzz-xg-3.png',
},
{
pid: 4,
alt: 'gitee 开源项目推广,日增 star 70',
src: 'https://oss.dev33.cn/sa-token/more/syzz-xg-4.png',
}
]
}
,anim: 5 //0-6的选择指定弹出图片动画类型默认随机请注意3.0之前的版本用shift参数
});
}
</script>
</body>
</html>

View File

@@ -124,7 +124,7 @@ SaTokenContext 是对接不同框架的上下文接口,注入流程和第二
### 6、发布代码
插件开发完毕之后你可以将其pr到官方仓库,或:
插件开发完毕之后,你可以将其 pr 到 [sa-token-three-plugin](https://gitee.com/sa-tokens/sa-token-three-plugin),或:
上传到 gitee/github 作为独立项目维护,并发布到 Maven 中央仓库,参考这篇:[https://juejin.cn/post/6844904104834105358](https://juejin.cn/post/6844904104834105358)

View File

@@ -31,11 +31,9 @@
</a>
</div>
<nav class="nav-right">
<div class="zk-box p-none">
<!-- <div class="zk-box p-none">
<a class="wzi" href="javascript:;">
<!-- <span>背景 </span> -->
<img class="theme-btn" src="static/icon/theme.svg">
<!-- <span class="zk-icon"></span> -->
</a>
<div class="zk-context theme-box">
<div>
@@ -52,14 +50,9 @@
<span style="background-color: #ebe5dd;"></span>
<span style="background-color: #e8f4ff;"></span>
<!-- <span style="background-color: #F0DAD2;"></span> -->
<!-- <span style="background-color: #f5d5d5;"></span> -->
<!-- <span style="background-color: #FFFFE0;"></span> -->
<!-- <span style="background-color: #eeeeee;"></span> -->
<!-- <span style="background-color: #f5fafe;"></span> -->
</div>
</div>
</div>
</div> -->
<a class="wzi" href="index.html">首页</a>
<a class="wzi" href="doc.html">文档</a>
<a class="p-none wzi" href="doc.html#/more/link">案例</a>
@@ -85,7 +78,7 @@
<a href="doc.html#/fun/sa-token-test">在线考试</a>
<a href="doc.html#/fun/issue-template">在线提问</a>
<!-- <a href="https://wj.qq.com/s2/10852322/0d8b/" target="_blank">需求提交</a> -->
<a href="https://wj.qq.com/s2/8475114/2f6a/" target="_blank">问卷调查</a>
<a href="doc.html#/more/wenjuan">问卷调查</a>
</div>
</div>
</div>
@@ -109,13 +102,16 @@
<div class="main-box">
<div class="content-box">
<!-- <div class="fenge"></div> -->
<h1>Sa-Token<small>v1.37.0</small></h1>
<div class="sub-title">一个轻量级 java 权限认证框架,让鉴权变得简单、优雅!</div>
<h1>Sa-Token<small>v1.38.0</small></h1>
<div class="sub-title">
<span class="sub-title-nr">一个轻量级 java 权限认证框架,让鉴权变得简单、优雅!</span>
<div class="gb-cursor">&nbsp;</div>
</div>
<div class="btn-box">
<a class="abtn" href="https://gitee.com/dromara/sa-token" target="_blank">Gitee</a>
<a class="abtn" href="https://github.com/dromara/sa-token" target="_blank">GitHub</a>
<a class="abtn" href="doc.html#/more/join-group" target="_self">加入讨论群</a>
<a class="abtn doc-btn" href="doc.html" target="_self">开发文档</a>
<a class="abtn doc-btn" href="doc.html" target="_self">现在出发 →</a>
<!-- <a href="https://gitee.com/dromara/sa-token" target="_blank">集成案例</a> -->
</div>
<h4 align="center" class="badge-box">
@@ -218,14 +214,14 @@
<img src="https://oss.dev33.cn/sa-token/awards/dromara.jpg?x-oss-process=style/st" /> <br>
<p>Dromara 组织顶尖项目(之一)</p>
</div>
<!-- <div class="swiper-slide" style="width: 750px;">
<img src="https://oss.dev33.cn/sa-token/awards/gitee-star-10k.png" /> <br>
<p>Gitee stars 超 10k+</p>
<div class="swiper-slide" style="width: 750px;">
<img src="https://oss.dev33.cn/sa-token/awards/gitee-top-1.png" /> <br>
<p>Gitee 项目推荐榜 top 1</p>
</div>
<div class="swiper-slide" style="width: 750px;">
<img src="https://oss.dev33.cn/sa-token/awards/github-star-10k.png" /> <br>
<p>GitHub stars 超 10k+</p>
</div> -->
<img src="https://oss.dev33.cn/sa-token/awards/github-star-15k.png" /> <br>
<p>GitHub stars 超 15k+</p>
</div>
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
@@ -424,12 +420,12 @@
<a href="http://www.jmwl51.com/" target="_blank" title="济南极梦网络科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/jimeng.png">
</a>
<a href="https://uniadmin.jiangruyi.com/" target="_blank" title="南京星意信息科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/uniadmin.png">
</a>
<a href="http://www.tuodan.tech/" target="_blank" title="深圳加速脱单科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/tuodan.jpeg">
</a>
<a href="https://uniadmin.jiangruyi.com/" target="_blank" title="南京星意信息科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/uniadmin.png">
</a>
<a href="https://www.yangxuwang.com/" target="_blank" title="上海阳旭网络科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/shouxin.png">
</a>
@@ -491,15 +487,15 @@
<a href="https://www.aegis-info.com/" target="_blank" title="北京擎盾信息科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/beijingqingdun.png">
</a>
<a href="https://mimirii.com/" target="_blank" title="西安米默网络科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/mimokeji.png">
</a>
<a href="https://www.geostar.com.cn/" target="_blank" title="吉奥时空">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/jieaoshikong.png">
</a>
<a href="http://www.stbella.cn/" target="_blank" title="贝康国际">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/beikangguoji.png">
</a>
<a href="https://mimirii.com/" target="_blank" title="西安米默网络科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/mimokeji.png">
</a>
<a href="http://www.chually.cn/" target="_blank" title="湖北楚商联盟金融信息服务有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/chushangjinfu.png">
</a>
@@ -512,18 +508,18 @@
<a href="https://hxp.liuxin.online/" target="_blank" title="沪小漂">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/hero.png">
</a>
<a href="https://www.mall4j.com/" target="_blank" title="广州市蓝海创新科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/guangzhoulanhai.png">
</a>
<a href="https://www.brath.cn" target="_blank" title="荔知AI助手">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/lizhi-ai.png">
</a>
<a href="http://www.njhrchina.top/" target="_blank" title="南京桓瑞软件科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/nanjing-hengrui.png">
</a>
<a href="https://www.ninthpalace.com/" target="_blank" title="苏州九宫数字科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/jiugongshuzi.png">
</a>
<a href="https://www.mall4j.com/" target="_blank" title="广州市蓝海创新科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/guangzhoulanhai.png">
</a>
<a href="http://www.njhrchina.top/" target="_blank" title="南京桓瑞软件科技有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/nanjing-hengrui.png">
</a>
<a href="https://sohelp.net/" target="_blank" title="宁波互邦软件有限公司">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/com/ningbohubang.png">
</a>
@@ -551,7 +547,7 @@
<h2 class="s-title">
Dromara 成员项目
</h2>
<div class="com-box com-box-you">
<div class="com-box com-box-you table-show-pj">
<a href="https://gitee.com/dromara/TLog" target="_blank">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/link/tlog.png"
msg="一个轻量级的分布式日志标记追踪神器10分钟即可接入自动对日志打标签完成微服务的链路追踪">
@@ -773,6 +769,18 @@
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/link/mybatis-jpa-extra.png"
msg="扩展MyBatis JPA支持简化CUID操作增强SELECT分页查询">
</a>
<a href="https://newcar.js.org/zh/" target="_blank">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/link/newcar.png"
msg="现代化的动画引擎">
</a>
<a href="http://warm-flow.cn" target="_blank">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/link/warm-flow.png"
msg="国产自研工作流,其特点简洁(只有6张表)但又不简单,五脏俱全,组件独立,可扩展,可满足中小项目的组件。">
</a>
<a href="https://gitee.com/dromara/dy-java" target="_blank">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/link/dy-java.png"
msg="DyJava是一款功能强大的抖音Java开发工具包">
</a>
<a href="https://dromara.org/zh/projects/" target="_blank">
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/link/dromara.png"
msg="让每一位开源爱好者,体会到开源的快乐。">
@@ -782,11 +790,11 @@
<p>
为往圣继绝学,一个人或许能走的更快,但一群人会走的更远。
</p>
<div style=" margin: 40px 14px 0; padding: 20px 0 10px; background-color: #f4f5f7;">
<!-- <div style=" margin: 40px 14px 0; padding: 20px 0 10px; background-color: #f4f5f7;">
<h3 style="padding: 0px 0 10px; ">Dromara 知识星球</h3>
<img class="lazy" data-original="https://oss.dev33.cn/sa-token/dromara-xingqiu--sa-token.jpg"
style="width: 300px;">
</div>
</div> -->
</div>
<div style="height: 30px;"></div>
</div>
@@ -914,7 +922,7 @@
</style>
<div class="foot-box" id="foot">
<div class="s-width" style="text-align: center;">
Copyright ©2022 Sa-Token java权限认证 | sa-token.cc | <a href="https://beian.miit.gov.cn/"
Copyright ©2024 Sa-Token java权限认证 | sa-token.cc | <a href="https://beian.miit.gov.cn/"
target="_blank">鲁ICP备18046274号-4</a>
</div>
</div>
@@ -1009,62 +1017,62 @@
<!-- 修改背景颜色 -->
<script>
// 绑定修改背景色的按钮事件
$('.theme-box span').click(function() {
let bgColor = this.style.backgroundColor;
setBg(bgColor);
localStorage.setItem('bg-color-value', bgColor)
})
// 读取上次记录
let bgColor = localStorage.getItem('bg-color-value');
if (bgColor) {
setBg(bgColor);
}
// // 绑定修改背景色的按钮事件
// $('.theme-box span').click(function() {
// let bgColor = this.style.backgroundColor;
// setBg(bgColor);
// localStorage.setItem('bg-color-value', bgColor)
// })
// // 读取上次记录
// let bgColor = localStorage.getItem('bg-color-value');
// if (bgColor) {
// setBg(bgColor);
// }
// 设置背景颜色
function setBg(bgColor) {
console.log('---- 背景颜色设定为:', bgColor);
// // 设置背景颜色
// function setBg(bgColor) {
// console.log('---- 背景颜色设定为:', bgColor);
// -------- 设置 body 背景
document.body.style.backgroundColor = bgColor;
// // -------- 设置 body 背景
// document.body.style.backgroundColor = bgColor;
// -------- 设置 header 头背景
// 如果是 16 进制,转 rgba
if (bgColor.indexOf('#') == 0) {
bgColor = hexToRgba(bgColor, 0.97);
}
// 如果是 rgb转 rgba
else if (bgColor.match(/\,/g).length == 2) {
bgColor = bgColor.replace(')', ' ,0.97)');
}
// // -------- 设置 header 头背景
// // 如果是 16 进制,转 rgba
// if (bgColor.indexOf('#') == 0) {
// bgColor = hexToRgba(bgColor, 0.97);
// }
// // 如果是 rgb转 rgba
// else if (bgColor.match(/\,/g).length == 2) {
// bgColor = bgColor.replace(')', ' ,0.97)');
// }
document.querySelector('.doc-header').style.backgroundColor = bgColor;
}
// document.querySelector('.doc-header').style.backgroundColor = bgColor;
// }
// 16进制 转 rgba
function hexToRgba(str, a) {
a = a || 1;
// // 16进制 转 rgba
// function hexToRgba(str, a) {
// a = a || 1;
var reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
if (!reg.test(str)) {
return;
}
let newStr = (str.toLowerCase()).replace(/\#/g, '')
let len = newStr.length;
if (len == 3) {
let t = ''
for (var i = 0; i < len; i++) {
t += newStr.slice(i, i + 1).concat(newStr.slice(i, i + 1))
}
newStr = t
}
let arr = []; //将字符串分隔,两个两个的分隔
for (var i = 0; i < 6; i = i + 2) {
let s = newStr.slice(i, i + 2)
arr.push(parseInt("0x" + s))
}
return 'rgb(' + arr.join(",") + ', ' + a + ')';
}
// var reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
// if (!reg.test(str)) {
// return;
// }
// let newStr = (str.toLowerCase()).replace(/\#/g, '')
// let len = newStr.length;
// if (len == 3) {
// let t = ''
// for (var i = 0; i < len; i++) {
// t += newStr.slice(i, i + 1).concat(newStr.slice(i, i + 1))
// }
// newStr = t
// }
// let arr = []; //将字符串分隔,两个两个的分隔
// for (var i = 0; i < 6; i = i + 2) {
// let s = newStr.slice(i, i + 2)
// arr.push(parseInt("0x" + s))
// }
// return 'rgb(' + arr.join(",") + ', ' + a + ')';
// }
</script>
<!-- 图片懒加载 -->
@@ -1095,5 +1103,31 @@
}
</script>
<script>
// 逐字打印效果
var tcStr = '一个轻量级 java 权限认证框架,让鉴权变得简单、优雅!';
var con = $('.sub-title .sub-title-nr');
var index = 1;
var length = tcStr.length;
var tId = null;
function start(){
con.text(tcStr.charAt(0));
tId = setInterval(function(){
con.append(tcStr.charAt(index));
if(index++ === length){
clearInterval(tId);
index = 1;
setTimeout(function(){
start()
}, 3000)
}
}, 90);
}
start();
</script>
</body>
</html>

View File

@@ -534,7 +534,35 @@ public class SaTokenContextByPatternsRequestCondition extends SaTokenContextForS
```
### QWebflux 环境集成,或者 SpringCloud Gateway 环境集成后,过滤器里路由拦截鉴权报错:`java.lang.NoSuchFieldError: defaultInstance`
``` java
java.lang.NoSuchFieldError: defaultInstance
at cn.dev33.satoken.spring.pathmatch.SaPathPatternParserUtil.match(SaPathPatternParserUtil.java:40)
at cn.dev33.satoken.reactor.spring.SaTokenContextForSpringReactor.matchPath(SaTokenContextForSpringReactor.java:34)
at cn.dev33.satoken.router.SaRouter.isMatch(SaRouter.java:58)
at cn.dev33.satoken.router.SaRouter.isMatch(SaRouter.java:72)
...
```
原因SpringBoot 版本用的太低了,导致一些类不存在。
- 方案一:升级项目的 SpringBoot 版本至 `2.3.x` 以上
- 方案二:像上面的问题解决方案一样,重写一下相关类:
``` java
/**
* 自定义 SaTokenContext 实现类,重写 matchPath 方法,将 PathPatternParser.defaultInstance 改为 SaPathMatcherHolder.getPathMatcher()
*/
@Primary
@Component
public class SaTokenContextByPatternsRequestCondition extends SaTokenContextForSpringReactor {
@Override
public boolean matchPath(String pattern, String path) {
return SaPathMatcherHolder.getPathMatcher().match(pattern, path);
}
}
```

View File

@@ -73,3 +73,5 @@ xxx 商品名称
- 1、目前不接受 Sa-Token 官网文档插入广告推广,只接受一次性商业赞助推广。
- 2、助力开源项目如果您要推广的是一个开源项目赞助金额可打五折赞助 100 元即可。
- 3、如果你的开源项目集成了 Sa-Token可以免费得到推广机会一次。**请大胆联系我们,不要害羞!**
<button class="syzz-show-btn" onclick="showSyzz()">部分推广效果截图(点击查看)</button>

View File

@@ -1,5 +1,59 @@
# 更新日志
### v1.38.0 @2023-10-18
- sa-token-core
- 修复:修复 `StpUtil.getSessionByLoginId(xx)` 参数为 null 时创建无效 `SaSession` 的 bug。
- 优化:在 `SpringBoot 3.x` 版本下错误的引入依赖时将得到启动失败的提示。 (感谢`Uncarbon`提交的pr
- 优化进一步优化权限校验算法hasXxx API 只会返回 true 或 false不再抛出异常。
- 重构:`InvalidContextException` 更名为 `SaTokenContextException`**[已做向下兼容处理]**
- 重构:彻底删除 `NotPermissionException` 异常中的 `getCode()` 方法。 **[过期API清理]**
- 重构:重构 `SaTokenException` 类方法 `throwBy-`>`notTrue``throwByNull-`>`notEmpty`。**[已做向下兼容处理]**
- 重构:`StpUtil.getSessionBySessionId` 提供的 `SessionId` 为空时将直接抛出异常而不是再返回null。**[不向下兼容]**
- 新增:新增 `Http Digest` 认证模块简单实现。 **[重要]**
- 重构:更换 `HttpBasic` 认证模块包名。 **[已做向下兼容处理]**
- 新增:新增 `StpUtil.getLoginDeviceByToken(xxx)` 方法,用于获取任意 token 的登录设备类型。
- 新增:新增 `StpUtil.getTokenLastActiveTime()` 方法,获取当前 token 最后活跃时间。
- 修复:修复“当登录时指定 timeout 小于全局 timeout 时,`Account-Session` 有效期为全局 timeout”的问题。
- 优化:首次获取 `Token-Session` 时,其有效期将保持和 token 有效期相同,而不是再是全局 timeout 值。
- 移除:移除 `SaSignConfig``isCheckNonce` 配置项。 **[不向下兼容]**
- 新增:`SaSignTemplate#checkRequest` 增加“可指定参与签名参数”的功能。
- 重构:将部分加密算法设置为过期。
- 重构:优化 token 读取策略空字符串将视为没有提交token。
- 修复:`sa-token-bom` 补全缺失依赖。
- 优化:二级认证校验之前必须先通过登录认证校验。
- 修复:修复 `StpUtil.getLoginId(T defaultValue)` 传入 null 时无法正确返回值的bug。
- sa-token-sso
- 优化SSO 模式三API 调用签名校验时,限定参与签名的参数列表,更安全。
- 新增:新增 `autoRenewTimeout` 配置项:是否在每次下发 ticket 时,自动续期 token 的有效期(根据全局 timeout 值)
- 新增:`SaSsoConfig` 新增配置 `isCheckSign`(是否校验参数签名),方便本地开发时的调试。
- 新增:`SaSsoConfig` 新增配置 `currSsoLogin`,用于强制指定当前系统的 sso 登录地址。
- 重构:整体重构 `sa-token-sso` 模块,将 `server` 端和 `client` 端代码拆分。 **[重要]** **[不向下兼容]**
- 新增:`SaSsoConfig` 配置项 `ssoLogoutCall` 重命名为 `currSsoLogoutCall`。**[已做向下兼容处理]**
- 重构:模式三在校验 Ticket 时,也将强制校验签名才能调通请求。**[不向下兼容]**
- 新增:新增 `maxRegClient` 配置项,用于控制模式三下 client 注册数量。
- 新增:新增不同 SSO Client 配置不同 `secret-key` 的方案。 **[重要]**
- 重构:匿名 client 将不再能解析出所有应用的 ticket。**[不向下兼容]**
- 新增:新增 `homeRoute` 配置项:在 ``/sso/auth`` 登录后不指定 redirect 参数的情况下默认跳转的路由。
- 优化优化登录有效期策略SSO Client 端登录时将延续 SSO Server 端的会话剩余有效期。
- 新增:新增 `checkTicketAppendData` 策略函数,用于在校验 ticket 后,给 sso-client 端追加返回信息。
- 新增SSO章节文档新增用户数据同步/迁移方案的建议。
- 修复:修复利用@字符可以绕过域名允许列表校验的漏洞**[漏洞修复]**
- 修复:禁止 `allow-url` 配置项 * 符号出现在中间位置,因为这有可能导致校验被绕过。 **[漏洞修复]**
- 新增插件/示例:
- 新增:新增插件 `sa-token-hutool-timed-cache`,用于整合 Hutool 缓存插件 TimedCache。 **[重要]**
- 新增:新增 SSM 架构整合 Sa-Token 简单示例。 **[重要]**
- 新增:新增 beetl 整合 Sa-Token 简单示例。 **[重要]**
- 文档:
- 部分章节将 `@Autowired` 更换为更合适的 `@PostConstruct`
- 新增过滤器执行顺序更改示例。
- 其它:
- 优化将跨域处理demo拆分为独立仓库。
- 优化:解决 springboot 集成 sa-token 后排除 jsckson 依赖无法成功启动的问题。
- 优化:解决 `sa-token-jwt` 模块重复设置 keyt 秘钥问题。(感谢`KonBAI`提交的pr
- 优化jwt模式 token 过期后,抛出的异常描述是 token 已过期,而不再是 token 无效。
- 修复:补齐 `sa-token-spring-aop` 模块中遗漏监听的注解。
### v1.37.0 @2023-10-18
- 修复:修复路由拦截鉴权可被绕过的问题。 **[漏洞修复]**
- 重构:未登录时调用鉴权 API 抛出未登录异常而不再是无权限异常。

View File

@@ -0,0 +1,5 @@
# 问卷调查
我们想以运营一款产品的心态来运营一个开源框架所以我们迫切希望您能够填写这份问卷这有6道选择题应该只会略微占用您1-3分钟的时间Sa-Token将会非常重视每一位粉丝的宝贵意见
[https://wj.qq.com/s2/14587150/b5b4/](https://wj.qq.com/s2/14587150/b5b4/)

View File

@@ -14,6 +14,7 @@
- sa-token-redis-fastjson2Redis集成包使用 fastjson2 序列化方式。
- sa-token-redisson-jacksonRedis集成包Redisson客户端使用jackson 序列化方式。
- sa-token-redisson-jackson2通用 redisson 集成方案 spring, solon, jfinal 等都可用)。
- sa-token-hutool-timed-cache集成 hutool 框架的 Timed-Cache 缓存方案(基于内存)。
有关 Redis 集成,详细参考:[集成Redis](/up/integ-redis)更多存储方式欢迎提交PR

View File

@@ -22,6 +22,7 @@ http://{host}:{port}/sso/auth
| :-------- | :-------- | :-------- |
| redirect | 是 | 登录成功后的重定向地址,一般填写 location.href从哪来回哪去 |
| mode | 否 | 授权模式,取值 [simple, ticket]simple=登录后直接重定向ticket=带着ticket参数重定向默认值为ticket |
| client | 否 | 客户端标识,可不填,代表是一个匿名应用,若填写了,则校验 ticket 时也必须是这个 client 才可以校验成功 |
访问接口后有两种情况:
- 情况一:当前会话在 SSO 认证中心未登录,会进入登录页开始登录。
@@ -40,7 +41,7 @@ http://{host}:{port}/sso/doLogin
| name | 是 | 用户名 |
| pwd | 是 | 密码 |
此接口属于 RestAPI (使用ajax访问),会进入后端配置的 `sso.setDoLoginHandle` 函数中,此函数的返回值即是此接口的响应值。
此接口属于 RestAPI (使用ajax访问),会进入后端配置的 `ssoServer.doLoginHandle` 函数中,此函数的返回值即是此接口的响应值。
另外需要注意:此接口并非只能携带 name、pwd 参数,因为你可以在方法里通过 `SaHolder.getRequest().getParam("xxx")` 来获取前端提交的其它参数。
@@ -58,6 +59,10 @@ http://{host}:{port}/sso/checkTicket
| :-------- | :-------- | :-------- |
| ticket | 是 | 在步骤 1 中授权重定向时的 ticket 参数 |
| ssoLogoutCall | 否 | 单点注销时的回调通知地址只在SSO模式三单点注销时需要携带此参数|
| client | 否 | 客户端标识,可不填,代表是一个匿名应用,若填写了,则必须填写的和 `/sso/auth` 登录时填写的一致才可以校验成功 |
| timestamp | 是 | 当前时间戳13位 |
| nonce | 是 | 随机字符串 |
| sign | 是 | 签名,生成算法:`md5( [client={client值}&]nonce={随机字符串}&[ssoLogoutCall={单点注销回调地址}&]ticket={ticket值}&timestamp={13位时间戳}&key={secretkey秘钥} )` 注:[]内容代表可选 |
返回值场景:
- 校验成功时:
@@ -66,7 +71,8 @@ http://{host}:{port}/sso/checkTicket
{
"code": 200,
"msg": "ok",
"data": "10001" // 此 ticket 指向的 loginId
"data": "10001", // 此 ticket 指向的 loginId
"remainSessionTimeout": 7200, // 此账号在 sso-server 端的会话剩余有效期单位s
}
```
@@ -106,6 +112,7 @@ http://{host}:{port}/sso/signout?back=xxx
| timestamp | 是 | 当前时间戳13位 |
| nonce | 是 | 随机字符串 |
| sign | 是 | 签名,生成算法:`md5( loginId={账号id}&nonce={随机字符串}&timestamp={13位时间戳}&key={secretkey秘钥} )` |
| client | 否 | 客户端标识,可不填,一般在帮助 “sso-server 端不同client不同秘钥” 的场景下找到对应秘钥时,才填写 |
例如:
``` url
@@ -198,7 +205,10 @@ http://{host}:{port}/sso/logoutCall
| loginId | 是 | 要注销的账号 id |
| timestamp | 是 | 当前时间戳13位 |
| nonce | 是 | 随机字符串 |
| sign | 是 | 签名,生成算法:`md5( loginId={账号id}&nonce={随机字符串}&timestamp={13位时间戳}&key={secretkey秘钥} )` |
| sign | 是 | 签名,生成算法:`md5( loginId={账号id}&nonce={随机字符串}&timestamp={13位时间戳}&key={secretkey秘钥} )` |
| client | 否 | 客户端标识,如果你在登录时向 sso-server 端传递了 client 值,那么在此处 sso-server 也会给你回传过来,否则此参数无值。如果此参数有值,则此参数也要参与签名,放在 loginId 参数前面(字典顺序) |
| autoLogout | 否 | 是否为“登录client超过最大数量”引起的自动注销true=超限系统自动注销false=用户主动发起注销)。如果此参数有值,则此参数也要参与签名,放在 client 参数前面(字典顺序) |
返回数据:

Some files were not shown because too many files have changed in this diff Show More