mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-10-26 10:39:02 +08:00
新增不同 SSO Client 配置不同秘钥的方案
This commit is contained in:
@@ -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 调用签名秘钥
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ server:
|
||||
port: 9000
|
||||
|
||||
# Sa-Token 配置
|
||||
sa-token:
|
||||
sa-token:
|
||||
# ------- SSO-模式一相关配置 (非模式一不需要配置)
|
||||
# cookie:
|
||||
# 配置 Cookie 作用域
|
||||
|
||||
@@ -3,7 +3,7 @@ server:
|
||||
port: 9032
|
||||
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
sa-token:
|
||||
# sso-client 相关配置
|
||||
sso-client:
|
||||
# client 标识
|
||||
|
||||
@@ -3,7 +3,7 @@ server:
|
||||
port: 9003
|
||||
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
sa-token:
|
||||
# sso-client 相关配置
|
||||
sso-client:
|
||||
# client 标识
|
||||
|
||||
@@ -41,12 +41,13 @@
|
||||
- [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/sso-questions)
|
||||
- [Sa-Sso-Pro:单点登录商业版](/sso/sso-pro)
|
||||
|
||||
- **OAuth2.0**
|
||||
|
||||
@@ -201,8 +201,10 @@ http://{host}:{port}/sso/logoutCall
|
||||
| loginId | 是 | 要注销的账号 id |
|
||||
| timestamp | 是 | 当前时间戳,13位 |
|
||||
| nonce | 是 | 随机字符串 |
|
||||
| client | 否 | 客户端标识,如果你在登录时向 sso-server 端传递了 client 值,那么在此处 sso-server 也会给你回传过来,否则此参数无值 |
|
||||
| sign | 是 | 签名,生成算法:`md5( loginId={账号id}&nonce={随机字符串}×tamp={13位时间戳}&key={secretkey秘钥} )` 如果 client 参数有值,则client也要参与签名,放在 loginId 参数签名(字典顺序)|
|
||||
| sign | 是 | 签名,生成算法:`md5( loginId={账号id}&nonce={随机字符串}×tamp={13位时间戳}&key={secretkey秘钥} )` |
|
||||
| client | 否 | 客户端标识,如果你在登录时向 sso-server 端传递了 client 值,那么在此处 sso-server 也会给你回传过来,否则此参数无值。如果此参数有值,则此参数也要参与签名,放在 loginId 参数前面(字典顺序) |
|
||||
| autoLogout | 否 | 是否为“登录client超过最大数量”引起的自动注销(true=超限系统自动注销,false=用户主动发起注销)。如果此参数有值,则此参数也要参与签名,放在 client 参数前面(字典顺序) |
|
||||
|
||||
|
||||
返回数据:
|
||||
|
||||
|
||||
119
sa-token-doc/sso/sso-diff-key.md
Normal file
119
sa-token-doc/sso/sso-diff-key.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# 不同 SSO Client 配置不同秘钥
|
||||
|
||||
在校验 ticket、单点注销等操作发起的 http 调用时,需要配置秘钥参数,像这样:
|
||||
|
||||
<!---------------------------- tabs:start ---------------------------->
|
||||
<!------------- tab:yaml 风格 ------------->
|
||||
``` yaml
|
||||
sa-token:
|
||||
sign:
|
||||
# API 接口调用秘钥
|
||||
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
||||
```
|
||||
<!------------- tab:properties 风格 ------------->
|
||||
``` properties
|
||||
# 接口调用秘钥
|
||||
sa-token.sign.secret-key=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
||||
```
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
||||
|
||||
如果 SSO Client 端和 SSO Server 端配置的秘钥不同,则无法调通请求,显示无效签名:
|
||||
``` js
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "无效签名:9f1b453817bfeac56d2f772a66c01eb2",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
如果你有多个 SSO Client,你可能想让每个应用配置不同的秘钥,让它们彼此之间不能互相“冒充”,怎么做呢?
|
||||
|
||||
### 1、首先在 SSO Client 端,你需要配置上不同的 Client 标识参数:
|
||||
|
||||
例如在 client1 我们配置上:
|
||||
|
||||
<!---------------------------- tabs:start ---------------------------->
|
||||
<!------------- tab:yaml 风格 ------------->
|
||||
``` yaml
|
||||
sa-token:
|
||||
sso-client:
|
||||
# 当前 client 标识
|
||||
client: sso-client1
|
||||
# ...
|
||||
sign:
|
||||
# sso-client1 使用的秘钥
|
||||
secret-key: secret-key-xxxx-1
|
||||
```
|
||||
<!------------- tab:properties 风格 ------------->
|
||||
``` properties
|
||||
# 当前 client 标识
|
||||
sa-token.sso-client.client=sso-client1
|
||||
|
||||
# sso-client1 使用的秘钥
|
||||
sa-token.sign.secret-key=secret-key-xxxx-1
|
||||
```
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
||||
|
||||
在 client2 我们配置上:
|
||||
|
||||
<!---------------------------- tabs:start ---------------------------->
|
||||
<!------------- tab:yaml 风格 ------------->
|
||||
``` yaml
|
||||
sa-token:
|
||||
sso-client:
|
||||
# 当前 client 标识
|
||||
client: sso-client2
|
||||
# ...
|
||||
sign:
|
||||
# sso-client2 使用的秘钥
|
||||
secret-key: secret-key-xxxx-2
|
||||
```
|
||||
<!------------- tab:properties 风格 ------------->
|
||||
``` properties
|
||||
# 当前 client 标识
|
||||
sa-token.sso-client.client=sso-client2
|
||||
|
||||
# sso-client2 使用的秘钥
|
||||
sa-token.sign.secret-key=secret-key-xxxx-2
|
||||
```
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
||||
|
||||
### 2、然后在 SSO Server 端,重写获取秘钥的函数
|
||||
|
||||
在 SSO Server 端新建 `CustomSaSsoServerTemplate.java`,继承 `SaSsoServerTemplate`,重写其 `getSignTemplate` 函数:
|
||||
|
||||
``` java
|
||||
/**
|
||||
* 自定义 SaSsoServerTemplate 子类
|
||||
*/
|
||||
@Component
|
||||
public class CustomSaSsoServerTemplate extends SaSsoServerTemplate {
|
||||
|
||||
// 存储所有 client 的秘钥
|
||||
static Map<String, SaSignTemplate> signMap = new HashMap<>();
|
||||
static {
|
||||
signMap.put("sso-client1", new SaSignTemplate(new SaSignConfig("secret-key-xxxx-1")));
|
||||
signMap.put("sso-client2", new SaSignTemplate(new SaSignConfig("secret-key-xxxx-2")));
|
||||
signMap.put("sso-client3", new SaSignTemplate(new SaSignConfig("secret-key-xxxx-3")));
|
||||
// ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaSignTemplate getSignTemplate(String client) {
|
||||
// 先从自定义的 signMap 中获取
|
||||
SaSignTemplate saSignTemplate = signMap.get(client);
|
||||
if (saSignTemplate != null) {
|
||||
return saSignTemplate;
|
||||
}
|
||||
// 找不到就返回全局默认的 SaSignTemplate
|
||||
return SaManager.getSaSignTemplate();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
至此完成,其它代码一切照旧。
|
||||
|
||||
|
||||
@@ -363,6 +363,9 @@ forest:
|
||||
``` properties
|
||||
# 接口调用秘钥
|
||||
sa-token.sign.secret-key=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
||||
|
||||
# 关闭 forest 请求日志打印
|
||||
forest.log-enabled=false
|
||||
```
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ public class SaSsoClientProcessor {
|
||||
|
||||
// 无论登录时选择的是模式二还是模式三
|
||||
// 在注销时都应该按照模式三的方法,通过 http 请求调用 sso-server 的单点注销接口来做到全端下线
|
||||
if(cfg.getIsSlo() && ! cfg.getIsHttp()) {
|
||||
if(cfg.getIsSlo()) {
|
||||
return ssoLogoutByMode3();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user