mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
004a1b7ed9 | ||
|
|
bd92fbbed9 | ||
|
|
35cb81085c | ||
|
|
8f467bbc9c | ||
|
|
43c9452fb2 | ||
|
|
81709bcef8 | ||
|
|
fcab8b876e | ||
|
|
1a62c391ea | ||
|
|
1c05958d51 | ||
|
|
1850130e11 | ||
|
|
4be4ee54c2 | ||
|
|
dd533fba8e | ||
|
|
54114ebac6 | ||
|
|
26bf2bd478 | ||
|
|
e024457405 | ||
|
|
1ab5bbe3d6 | ||
|
|
89a69e5624 | ||
|
|
c3bd2018a2 | ||
|
|
535c8e972f | ||
|
|
b4baa4229f | ||
|
|
bdac07d7a0 | ||
|
|
b2416ae43d | ||
|
|
c5c3253171 | ||
|
|
6d4496897d | ||
|
|
ea546c7adb | ||
|
|
f612c87e3a | ||
|
|
adb600d643 | ||
|
|
c508e99281 | ||
|
|
d6f2be4a2e | ||
|
|
c169721ebf | ||
|
|
f35a6f6ad8 | ||
|
|
aa47362cfa | ||
|
|
55821d09c6 | ||
|
|
b23aa55ffa | ||
|
|
e781664840 | ||
|
|
9261a2687c | ||
|
|
7556796eaa | ||
|
|
278dd42695 | ||
|
|
1bbf127b95 | ||
|
|
73843741af | ||
|
|
60fdc4ca2a | ||
|
|
ce40fe2dad | ||
|
|
cc9fe4c08b | ||
|
|
b926bad13d | ||
|
|
83ac203631 | ||
|
|
f4dda6eb6c | ||
|
|
78fd26e9db | ||
|
|
9e37896bb0 | ||
|
|
c1bc858f14 | ||
|
|
42d94827c1 | ||
|
|
1ba8d6f8d4 | ||
|
|
9680d6cb9f | ||
|
|
ce4d12b0ca | ||
|
|
b92ba4de87 | ||
|
|
7f5ae11961 | ||
|
|
c0a993a0f5 | ||
|
|
2eacec9539 | ||
|
|
21948fbf7e | ||
|
|
c850874e49 | ||
|
|
64abd69715 | ||
|
|
5a7463dc91 | ||
|
|
cf1f255a4a | ||
|
|
4c216069aa | ||
|
|
7ee27add84 | ||
|
|
27618484dc | ||
|
|
8d6b648d4b | ||
|
|
c52fd9c86f | ||
|
|
818c1cb4eb | ||
|
|
14a97a1fcb |
137
README.md
137
README.md
@@ -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.x,jdk 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-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="微信群" />
|
||||
<!--  -->
|
||||
|
||||
(扫码添加微信,备注:sa-token,邀您加入群聊)
|
||||
|
||||
|
||||
@@ -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 ..
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 调用签名秘钥
|
||||
*
|
||||
|
||||
@@ -125,6 +125,9 @@ public interface SaErrorCode {
|
||||
/** 获取 SaSession 时提供的 SessionId 为空 */
|
||||
int CODE_11072 = 11072;
|
||||
|
||||
/** 获取 Token-Session 时提供的 token 为空 */
|
||||
int CODE_11073 = 11073;
|
||||
|
||||
|
||||
// ------------
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 里面会有多个异常,我们随便抛出一个即可
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------- 会话管理 -------------------
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ sa-token:
|
||||
sa-token-dao: #名字可以随意取
|
||||
redis:
|
||||
server: "localhost:6379"
|
||||
password: 123456
|
||||
# password: 123456
|
||||
db: 1
|
||||
maxTotal: 200
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -3,7 +3,7 @@ server:
|
||||
port: 9000
|
||||
|
||||
# Sa-Token 配置
|
||||
sa-token:
|
||||
sa-token:
|
||||
# ------- SSO-模式一相关配置 (非模式一不需要配置)
|
||||
# cookie:
|
||||
# 配置 Cookie 作用域
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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版本) 启动成功");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 +
|
||||
"×tamp=" + timestamp +
|
||||
"&nonce=" + nonce +
|
||||
|
||||
@@ -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 + "×tamp=" + timestamp + "&key=" + secretkey);
|
||||
public static String getSign(Object loginId, String timestamp, String nonce) {
|
||||
return md5("loginId=" + loginId + "&nonce=" + nonce + "×tamp=" + timestamp + "&key=" + secretKey);
|
||||
}
|
||||
// 单点注销回调时构建签名
|
||||
public static String getSignByLogoutCall(Object loginId, String autoLogout, String timestamp, String nonce) {
|
||||
return md5("autoLogout=" + autoLogout + "&loginId=" + loginId + "&nonce=" + nonce + "×tamp=" + timestamp + "&key=" + secretKey);
|
||||
}
|
||||
// 校验ticket 时构建签名
|
||||
public static String getSignByTicket(String ticket, String ssoLogoutCall, String timestamp, String nonce) {
|
||||
return md5("nonce=" + nonce + "&ssoLogoutCall=" + ssoLogoutCall + "&ticket=" + ticket + "×tamp=" + timestamp + "&key=" + secretKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 9001
|
||||
port: 9004
|
||||
|
||||
forest:
|
||||
# 打开/关闭Forest请求日志(默认为 true)
|
||||
|
||||
12
sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client-test2/.gitignore
vendored
Normal file
12
sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client-test2/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.idea/
|
||||
|
||||
.factorypath
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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服务器连接端口
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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());
|
||||
})
|
||||
;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 的登录设备类型
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"> </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>
|
||||
@@ -534,7 +534,35 @@ public class SaTokenContextByPatternsRequestCondition extends SaTokenContextForS
|
||||
```
|
||||
|
||||
|
||||
### Q:Webflux 环境集成,或者 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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -73,3 +73,5 @@ xxx 商品名称
|
||||
- 1、目前不接受 Sa-Token 官网文档插入广告推广,只接受一次性商业赞助推广。
|
||||
- 2、助力开源项目:如果您要推广的是一个开源项目,赞助金额可打五折,即:赞助 100 元即可。
|
||||
- 3、如果你的开源项目集成了 Sa-Token,可以免费得到推广机会一次。**请大胆联系我们,不要害羞!**
|
||||
|
||||
<button class="syzz-show-btn" onclick="showSyzz()">部分推广效果截图(点击查看)</button>
|
||||
@@ -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 抛出未登录异常而不再是无权限异常。
|
||||
|
||||
5
sa-token-doc/more/wenjuan.md
Normal file
5
sa-token-doc/more/wenjuan.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# 问卷调查
|
||||
|
||||
我们想以运营一款产品的心态来运营一个开源框架,所以我们迫切希望您能够填写这份问卷,这有6道选择题,应该只会略微占用您1-3分钟的时间,Sa-Token将会非常重视每一位粉丝的宝贵意见!
|
||||
|
||||
[https://wj.qq.com/s2/14587150/b5b4/](https://wj.qq.com/s2/14587150/b5b4/)
|
||||
@@ -14,6 +14,7 @@
|
||||
- sa-token-redis-fastjson2:Redis集成包,使用 fastjson2 序列化方式。
|
||||
- sa-token-redisson-jackson:Redis集成包,Redisson客户端使用,jackson 序列化方式。
|
||||
- sa-token-redisson-jackson2:通用 redisson 集成方案 (spring, solon, jfinal 等都可用)。
|
||||
- sa-token-hutool-timed-cache:集成 hutool 框架的 Timed-Cache 缓存方案(基于内存)。
|
||||
|
||||
有关 Redis 集成,详细参考:[集成Redis](/up/integ-redis),更多存储方式欢迎提交PR
|
||||
|
||||
|
||||
@@ -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值}×tamp={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={随机字符串}×tamp={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={随机字符串}×tamp={13位时间戳}&key={secretkey秘钥} )` |
|
||||
| sign | 是 | 签名,生成算法:`md5( loginId={账号id}&nonce={随机字符串}×tamp={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
Reference in New Issue
Block a user