diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaSignConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaSignConfig.java index 1e5cd72d..995ab523 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaSignConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaSignConfig.java @@ -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 调用签名秘钥 * diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java index 1076511d..4ea4f9d4 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java @@ -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; } /** diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/resources/application.yml index 04395bf6..901f2838 100644 --- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/resources/application.yml @@ -3,7 +3,7 @@ server: port: 9000 # Sa-Token 配置 -sa-token: +sa-token: # ------- SSO-模式一相关配置 (非模式一不需要配置) # cookie: # 配置 Cookie 作用域 diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client-test2/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client-test2/src/main/resources/application.yml index ebec4dde..f829c1fe 100644 --- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client-test2/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client-test2/src/main/resources/application.yml @@ -3,7 +3,7 @@ server: port: 9032 # sa-token配置 -sa-token: +sa-token: # sso-client 相关配置 sso-client: # client 标识 diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/resources/application.yml index ef48e853..b5426f8f 100644 --- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/resources/application.yml @@ -3,7 +3,7 @@ server: port: 9003 # sa-token配置 -sa-token: +sa-token: # sso-client 相关配置 sso-client: # client 标识 diff --git a/sa-token-doc/_sidebar.md b/sa-token-doc/_sidebar.md index 9a575347..c017ef18 100644 --- a/sa-token-doc/_sidebar.md +++ b/sa-token-doc/_sidebar.md @@ -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** diff --git a/sa-token-doc/sso/sso-apidoc.md b/sa-token-doc/sso/sso-apidoc.md index 14d29257..2d03713a 100644 --- a/sa-token-doc/sso/sso-apidoc.md +++ b/sa-token-doc/sso/sso-apidoc.md @@ -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 参数前面(字典顺序) | + 返回数据: diff --git a/sa-token-doc/sso/sso-diff-key.md b/sa-token-doc/sso/sso-diff-key.md new file mode 100644 index 00000000..17fb0344 --- /dev/null +++ b/sa-token-doc/sso/sso-diff-key.md @@ -0,0 +1,119 @@ +# 不同 SSO Client 配置不同秘钥 + +在校验 ticket、单点注销等操作发起的 http 调用时,需要配置秘钥参数,像这样: + + + +``` yaml +sa-token: + sign: + # API 接口调用秘钥 + secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor +``` + +``` properties +# 接口调用秘钥 +sa-token.sign.secret-key=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor +``` + + + +如果 SSO Client 端和 SSO Server 端配置的秘钥不同,则无法调通请求,显示无效签名: +``` js +{ + "code": 500, + "msg": "无效签名:9f1b453817bfeac56d2f772a66c01eb2", + "data": null +} +``` + +如果你有多个 SSO Client,你可能想让每个应用配置不同的秘钥,让它们彼此之间不能互相“冒充”,怎么做呢? + +### 1、首先在 SSO Client 端,你需要配置上不同的 Client 标识参数: + +例如在 client1 我们配置上: + + + +``` yaml +sa-token: + sso-client: + # 当前 client 标识 + client: sso-client1 + # ... + sign: + # sso-client1 使用的秘钥 + secret-key: secret-key-xxxx-1 +``` + +``` properties +# 当前 client 标识 +sa-token.sso-client.client=sso-client1 + +# sso-client1 使用的秘钥 +sa-token.sign.secret-key=secret-key-xxxx-1 +``` + + + +在 client2 我们配置上: + + + +``` yaml +sa-token: + sso-client: + # 当前 client 标识 + client: sso-client2 + # ... + sign: + # sso-client2 使用的秘钥 + secret-key: secret-key-xxxx-2 +``` + +``` properties +# 当前 client 标识 +sa-token.sso-client.client=sso-client2 + +# sso-client2 使用的秘钥 +sa-token.sign.secret-key=secret-key-xxxx-2 +``` + + + +### 2、然后在 SSO Server 端,重写获取秘钥的函数 + +在 SSO Server 端新建 `CustomSaSsoServerTemplate.java`,继承 `SaSsoServerTemplate`,重写其 `getSignTemplate` 函数: + +``` java +/** + * 自定义 SaSsoServerTemplate 子类 + */ +@Component +public class CustomSaSsoServerTemplate extends SaSsoServerTemplate { + + // 存储所有 client 的秘钥 + static Map 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(); + } +} +``` + +至此完成,其它代码一切照旧。 + + diff --git a/sa-token-doc/sso/sso-type2.md b/sa-token-doc/sso/sso-type2.md index 32d115ea..b19cb153 100644 --- a/sa-token-doc/sso/sso-type2.md +++ b/sa-token-doc/sso/sso-type2.md @@ -363,6 +363,9 @@ forest: ``` properties # 接口调用秘钥 sa-token.sign.secret-key=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor + +# 关闭 forest 请求日志打印 +forest.log-enabled=false ``` diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoClientProcessor.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoClientProcessor.java index 5401d2f8..6665ff9e 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoClientProcessor.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoClientProcessor.java @@ -150,7 +150,7 @@ public class SaSsoClientProcessor { // 无论登录时选择的是模式二还是模式三 // 在注销时都应该按照模式三的方法,通过 http 请求调用 sso-server 的单点注销接口来做到全端下线 - if(cfg.getIsSlo() && ! cfg.getIsHttp()) { + if(cfg.getIsSlo()) { return ssoLogoutByMode3(); }