diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/pom.xml b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/pom.xml
index 4e2f6b70..fbfa451c 100644
--- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/pom.xml
+++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/pom.xml
@@ -57,12 +57,12 @@
org.springframework.boot
spring-boot-starter-thymeleaf
-
-
+
+
- com.dtflys.forest
- forest-spring-boot-starter
- 1.5.26
+ cn.dev33
+ sa-token-forest
+ ${sa-token.version}
diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java
index 6e2e64ee..5986a9a2 100644
--- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java
+++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java
@@ -6,7 +6,6 @@ import cn.dev33.satoken.sso.config.SaSsoServerConfig;
import cn.dev33.satoken.sso.processor.SaSsoServerProcessor;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -50,19 +49,7 @@ public class SsoServerController {
}
return SaResult.error("登录失败!");
};
-
- // 配置 Http 请求处理器 (在模式三的单点注销功能下用到,如不需要可以注释掉)
- ssoServer.sendHttp = url -> {
- try {
- System.out.println("------ 发起请求:" + url);
- String resStr = Forest.get(url).executeAsString();
- System.out.println("------ 请求结果:" + resStr);
- return resStr;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- };
+
}
// 示例:获取数据接口(用于在模式三下,为 client 端开放拉取数据的接口)
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 dcea68c8..b8be854d 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
@@ -35,8 +35,9 @@ sa-token:
# 应用 sso-client3,采用模式三对接 (跨域、跨Redis)
sso-client3:
client: sso-client3
- secret-key: SSO-C3-kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
allow-url: "*"
+ secret-key: SSO-C3-kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
+ push-url: http://sa-sso-client1.com:9003/sso/pushC
# ---- 除了以上配置项,你还需要为 Sa-Token 配置http请求处理器(文档有步骤说明)
diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java
index 361d1cfb..56eda97d 100644
--- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java
+++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java
@@ -5,7 +5,6 @@ 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;
@@ -43,13 +42,7 @@ public class SsoClientController {
// 配置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;
- };
+
}
// 全局异常拦截
diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/pom.xml b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/pom.xml
index 13a2f663..7d328d7f 100644
--- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/pom.xml
+++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/pom.xml
@@ -53,15 +53,16 @@
org.apache.commons
commons-pool2
-
-
+
+
- com.dtflys.forest
- forest-spring-boot-starter
- 1.5.26
+ cn.dev33
+ sa-token-forest
+ ${sa-token.version}
-
-
+
+
+
diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java
index 2492688a..37578649 100644
--- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java
+++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java
@@ -5,7 +5,6 @@ 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;
@@ -45,13 +44,7 @@ public class SsoClientController {
// 配置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;
- };
+
}
// 查询我的账号信息
diff --git a/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/http/SaHttpTemplateForForest.java b/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/http/SaHttpTemplateForForest.java
index 9e24b800..e1e1d998 100644
--- a/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/http/SaHttpTemplateForForest.java
+++ b/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/http/SaHttpTemplateForForest.java
@@ -21,7 +21,7 @@ import com.dtflys.forest.Forest;
import java.util.Map;
/**
- * Http 转换器, Forest 版实现
+ * Http 请求处理器, Forest 版实现
*
* @author click33
* @since 1.43.0
diff --git a/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForForest.java b/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForForest.java
index dad3712a..ff1ffc64 100644
--- a/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForForest.java
+++ b/sa-token-plugin/sa-token-forest/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForForest.java
@@ -17,6 +17,7 @@ package cn.dev33.satoken.plugin;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.http.SaHttpTemplateForForest;
+import com.dtflys.forest.config.ForestConfiguration;
/**
* SaToken 插件安装:Http 请求处理器 - Forest 版
@@ -28,6 +29,10 @@ public class SaTokenPluginForForest implements SaTokenPlugin {
@Override
public void install() {
+ // 关闭 Forest 默认日志打印
+ ForestConfiguration.getDefaultConfiguration().setLogEnabled(false);
+
+ // 设置 Forest 作为 Http 请求处理器
SaManager.setSaHttpTemplate(new SaHttpTemplateForForest());
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientConfig.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientConfig.java
index 1e6abd9f..3d4537c7 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientConfig.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientConfig.java
@@ -16,9 +16,6 @@
package cn.dev33.satoken.sso.config;
-import cn.dev33.satoken.sso.error.SaSsoErrorCode;
-import cn.dev33.satoken.sso.exception.SaSsoException;
-import cn.dev33.satoken.sso.function.SendHttpFunction;
import cn.dev33.satoken.sso.function.TicketResultHandleFunction;
import cn.dev33.satoken.util.SaFoxUtil;
@@ -40,12 +37,12 @@ public class SaSsoClientConfig implements Serializable {
public String mode = "";
/**
- * 当前 Client 名称标识,用于和 ticket 码的互相锁定
+ * 当前 Client 标识
*/
public String client;
/**
- * 配置 Server 端主机总地址,拼接在 authUrl、checkTicketUrl、getDataUrl、sloUrl 属性前面,用以简化各种 url 配置
+ * 配置 Server 端主机总地址
*/
public String serverUrl;
@@ -54,11 +51,6 @@ public class SaSsoClientConfig implements Serializable {
*/
public String authUrl = "/sso/auth";
- /**
- * 单独配置 Server 端的 ticket 校验地址
- */
- public String checkTicketUrl = "/sso/checkTicket";
-
/**
* 单独配置 Server 端查询数据 getData 地址
*/
@@ -69,6 +61,11 @@ public class SaSsoClientConfig implements Serializable {
*/
public String sloUrl = "/sso/signout";
+ /**
+ * 单独配置 Server 端推送消息地址
+ */
+ public String pushUrl = "/sso/pushS";
+
/**
* 配置当前 Client 端的登录地址(为空时自动获取)
*/
@@ -80,12 +77,17 @@ public class SaSsoClientConfig implements Serializable {
public String currSsoLogoutCall;
/**
- * 是否打开单点注销功能
+ * 是否打开单点注销功能 (为 true 时,接收单点注销回调消息推送)
*/
public Boolean isSlo = true;
/**
- * 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、拉取数据getData)
+ * 是否注册单点登录注销回调 (为 true 时,登录时附带单点登录回调地址,并且开放 /sso/logoutCall 地址)
+ */
+ public Boolean regLogoutCall = false;
+
+ /**
+ * 是否打开模式三(此值为 true 时将使用 http 请求校验 ticket 值)
*/
public Boolean isHttp = false;
@@ -100,6 +102,47 @@ public class SaSsoClientConfig implements Serializable {
public Boolean isCheckSign = true;
+ // 额外添加的一些函数
+
+ /**
+ * @return 获取拼接url:Server 端单点登录授权地址
+ */
+ public String splicingAuthUrl() {
+ return SaFoxUtil.spliceTwoUrl(getServerUrl(), getAuthUrl());
+ }
+
+ /**
+ * @return 获取拼接url:Server 端查询数据 getData 地址
+ */
+ public String splicingGetDataUrl() {
+ return SaFoxUtil.spliceTwoUrl(getServerUrl(), getGetDataUrl());
+ }
+
+ /**
+ * @return 获取拼接url:Server 端单点注销地址
+ */
+ public String splicingSloUrl() {
+ return SaFoxUtil.spliceTwoUrl(getServerUrl(), getSloUrl());
+ }
+
+ /**
+ * @return 获取拼接url:单独配置 Server 端推送消息地址
+ */
+ public String splicingPushUrl() {
+ return SaFoxUtil.spliceTwoUrl(getServerUrl(), getPushUrl());
+ }
+
+
+ // -------------------- 所有回调函数 --------------------
+
+ /**
+ * SSO-Client端:自定义校验 ticket 返回值的处理逻辑 (每次从认证中心获取校验 ticket 的结果后调用)
+ *
参数:loginId, back
+ *
返回值:返回给前端的值
+ */
+ public TicketResultHandleFunction ticketResultHandle = null;
+
+
// get set
/**
@@ -183,22 +226,6 @@ public class SaSsoClientConfig implements Serializable {
return this;
}
- /**
- * @return 配置的 Server 端的 ticket 校验地址
- */
- public String getCheckTicketUrl() {
- return checkTicketUrl;
- }
-
- /**
- * @param checkTicketUrl 配置 Server 端的 ticket 校验地址
- * @return 对象自身
- */
- public SaSsoClientConfig setCheckTicketUrl(String checkTicketUrl) {
- this.checkTicketUrl = checkTicketUrl;
- return this;
- }
-
/**
* @return Server 端查询数据 getData 地址
*/
@@ -231,6 +258,26 @@ public class SaSsoClientConfig implements Serializable {
return this;
}
+ /**
+ * 获取 单独配置 Server 端推送消息地址
+ *
+ * @return /
+ */
+ public String getPushUrl() {
+ return this.pushUrl;
+ }
+
+ /**
+ * 设置 单独配置 Server 端推送消息地址
+ *
+ * @param pushUrl /
+ * @return 对象自身
+ */
+ public SaSsoClientConfig setPushUrl(String pushUrl) {
+ this.pushUrl = pushUrl;
+ return this;
+ }
+
/**
* @return 配置当前 Client 端的登录地址(为空时自动获取)
*/
@@ -318,6 +365,26 @@ public class SaSsoClientConfig implements Serializable {
return this;
}
+ /**
+ * 获取 是否注册单点登录注销回调 (为 true 时,登录时附带单点登录回调地址,并且开放 /sso/logoutCall 地址)
+ *
+ * @return /
+ */
+ public Boolean getRegLogoutCall() {
+ return this.regLogoutCall;
+ }
+
+ /**
+ * 设置 是否注册单点登录注销回调 (为 true 时,登录时附带单点登录回调地址,并且开放 /sso/logoutCall 地址)
+ *
+ * @param regLogoutCall /
+ * @return /
+ */
+ public SaSsoClientConfig setRegLogoutCall(Boolean regLogoutCall) {
+ this.regLogoutCall = regLogoutCall;
+ return this;
+ }
+
@Override
public String toString() {
return "SaSsoClientConfig ["
@@ -325,63 +392,16 @@ public class SaSsoClientConfig implements Serializable {
+ ", client=" + client
+ ", serverUrl=" + serverUrl
+ ", authUrl=" + authUrl
- + ", checkTicketUrl=" + checkTicketUrl
+ ", getDataUrl=" + getDataUrl
+ ", sloUrl=" + sloUrl
+ ", currSsoLogin=" + currSsoLogin
+ ", currSsoLogoutCall=" + currSsoLogoutCall
- + ", isSlo=" + isSlo
+ ", isHttp=" + isHttp
+ + ", isSlo=" + isSlo
+ + ", regLogoutCall=" + regLogoutCall
+ ", secretKey=" + secretKey
+ ", isCheckSign=" + isCheckSign
+ "]";
}
- // 额外添加的一些函数
-
- /**
- * @return 获取拼接url:Server 端单点登录授权地址
- */
- public String splicingAuthUrl() {
- return SaFoxUtil.spliceTwoUrl(getServerUrl(), getAuthUrl());
- }
-
- /**
- * @return 获取拼接url:Server 端的 ticket 校验地址
- */
- public String splicingCheckTicketUrl() {
- return SaFoxUtil.spliceTwoUrl(getServerUrl(), getCheckTicketUrl());
- }
-
- /**
- * @return 获取拼接url:Server 端查询数据 getData 地址
- */
- public String splicingGetDataUrl() {
- return SaFoxUtil.spliceTwoUrl(getServerUrl(), getGetDataUrl());
- }
-
- /**
- * @return 获取拼接url:Server 端单点注销地址
- */
- public String splicingSloUrl() {
- return SaFoxUtil.spliceTwoUrl(getServerUrl(), getSloUrl());
- }
-
-
- // -------------------- 所有回调函数 --------------------
-
- /**
- * SSO-Client端:自定义校验 ticket 返回值的处理逻辑 (每次从认证中心获取校验 ticket 的结果后调用)
- *
参数:loginId, back
- *
返回值:返回给前端的值
- */
- public TicketResultHandleFunction ticketResultHandle = null;
-
- /**
- * SSO-Client端:发送Http请求的处理函数
- */
- public SendHttpFunction sendHttp = url -> {
- throw new SaSsoException("请配置 Http 请求处理器").setCode(SaSsoErrorCode.CODE_30010);
- };
-
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientModel.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientModel.java
index d907f23d..b1e6a909 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientModel.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoClientModel.java
@@ -42,6 +42,11 @@ public class SaSsoClientModel implements Serializable {
*/
public String allowUrl = "*";
+ /**
+ * 是否打开模式三(此值为 true 时使用 http 调用方式进行消息通知)
+ */
+ public Boolean isHttp = false;
+
/**
* 是否打开单点注销功能
*/
@@ -52,7 +57,18 @@ public class SaSsoClientModel implements Serializable {
*/
public String secretKey;
- // 额外方法
+ /**
+ * 此 Client 端主机总地址
+ */
+ public String serverUrl;
+
+ /**
+ * 此 Client 端推送消息的地址
+ */
+ public String pushUrl = "/sso/pushC";
+
+
+ // 额外添加的一些函数
/**
* 以数组形式写入允许的授权回调地址
@@ -64,6 +80,25 @@ public class SaSsoClientModel implements Serializable {
return this;
}
+ /**
+ * 获取拼接 url:此 Client 端推送消息的地址
+ *
+ * @return /
+ */
+ public String splicingNoticeUrl() {
+ return SaFoxUtil.spliceTwoUrl(getServerUrl(), getPushUrl());
+ }
+
+ /**
+ * 判断是否配置了有效地推送地址
+ *
+ * @return /
+ */
+ public boolean isValidNoticeUrl() {
+ return SaFoxUtil.isUrl(splicingNoticeUrl());
+ }
+
+
// get set
/**
@@ -102,6 +137,22 @@ public class SaSsoClientModel implements Serializable {
return this;
}
+ /**
+ * @return isHttp 是否打开模式三
+ */
+ public Boolean getIsHttp() {
+ return isHttp;
+ }
+
+ /**
+ * @param isHttp 是否打开模式三
+ * @return 对象自身
+ */
+ public SaSsoClientModel setIsHttp(Boolean isHttp) {
+ this.isHttp = isHttp;
+ return this;
+ }
+
/**
* @return 是否打开单点注销功能
*/
@@ -138,13 +189,56 @@ public class SaSsoClientModel implements Serializable {
return this;
}
+ /**
+ * 获取 此 Client 端主机总地址
+ *
+ * @return serverUrl 此 Client 端主机总地址
+ */
+ public String getServerUrl() {
+ return this.serverUrl;
+ }
+
+ /**
+ * 设置 此 Client 端主机总地址
+ *
+ * @param serverUrl 此 Client 端主机总地址
+ * @return 对象自身
+ */
+ public SaSsoClientModel setServerUrl(String serverUrl) {
+ this.serverUrl = serverUrl;
+ return this;
+ }
+
+ /**
+ * 获取 此 Client 端推送消息的地址
+ *
+ * @return noticeUrl 此 Client 端推送消息的地址
+ */
+ public String getPushUrl() {
+ return this.pushUrl;
+ }
+
+ /**
+ * 设置 此 Client 端推送消息的地址
+ *
+ * @param pushUrl 此 Client 端推送消息的地址
+ * @return 对象自身
+ */
+ public SaSsoClientModel setPushUrl(String pushUrl) {
+ this.pushUrl = pushUrl;
+ return this;
+ }
+
@Override
public String toString() {
return "SaSsoClientModel ["
+ "client=" + client
+ ", allowUrl=" + allowUrl
+ ", isSlo=" + isSlo
+ + ", isHttp=" + isHttp
+ ", secretKey=" + secretKey
+ + ", serverUrl=" + serverUrl
+ + ", pushUrl=" + pushUrl
+ "]";
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoServerConfig.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoServerConfig.java
index cedde8fb..df59d9ce 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoServerConfig.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/config/SaSsoServerConfig.java
@@ -16,12 +16,9 @@
package cn.dev33.satoken.sso.config;
-import cn.dev33.satoken.sso.error.SaSsoErrorCode;
-import cn.dev33.satoken.sso.exception.SaSsoException;
import cn.dev33.satoken.sso.function.CheckTicketAppendDataFunction;
import cn.dev33.satoken.sso.function.DoLoginHandleFunction;
import cn.dev33.satoken.sso.function.NotLoginViewFunction;
-import cn.dev33.satoken.sso.function.SendHttpFunction;
import cn.dev33.satoken.sso.template.SaSsoServerTemplate;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
@@ -54,11 +51,6 @@ public class SaSsoServerConfig implements Serializable {
*/
public long ticketTimeout = 60 * 5;
- /**
- * 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
- */
- public String allowUrl = "*";
-
/**
* 主页路由:在 /sso/auth 登录后不指定 redirect 参数的情况下默认跳转的路由
*/
@@ -69,41 +61,43 @@ public class SaSsoServerConfig implements Serializable {
*/
public Boolean isSlo = true;
- /**
- * 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、获取userinfo)
- */
- public Boolean isHttp = false;
-
/**
* 是否在每次下发 ticket 时,自动续期 token 的有效期(根据全局 timeout 值)
*/
public Boolean autoRenewTimeout = false;
/**
- * 在 Access-Session 上记录 Client 信息的最高数量(-1=无限),超过此值将进行自动清退处理,先进先出
+ * 在 Account-Session 上记录 Client 信息的最高数量(-1=无限),超过此值将进行自动清退处理,先进先出
*/
public int maxRegClient = 32;
- /**
- * 是否允许匿名 Client 接入
- */
- public Boolean allowAnonClient = true;
-
/**
* 是否校验参数签名(方便本地调试用的一个配置项,生产环境请务必为true)
*/
public Boolean isCheckSign = true;
- /**
- * API 调用签名秘钥
- */
- public String secretKey;
-
/**
* Client 信息配置列表
*/
public Map clients = new LinkedHashMap<>();
+ // 匿名 Client 相关配置
+
+ /**
+ * 是否允许匿名 Client 接入
+ */
+ public Boolean allowAnonClient = true;
+
+ /**
+ * 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket) (匿名 client 使用)
+ */
+ public String allowUrl = "*";
+
+ /**
+ * API 调用签名秘钥 (全局默认 + 匿名 client 使用)
+ */
+ public String secretKey;
+
// 额外方法
@@ -128,6 +122,31 @@ public class SaSsoServerConfig implements Serializable {
}
+ // -------------------- 所有回调函数 --------------------
+
+
+ /**
+ * SSO-Server端:未登录时返回的View
+ */
+ public NotLoginViewFunction notLoginView = () -> {
+ return "当前会话在SSO-Server认证中心尚未登录(当前未配置登录视图)";
+ };
+
+ /**
+ * SSO-Server端:登录函数
+ */
+ public DoLoginHandleFunction doLoginHandle = (name, pwd) -> {
+ return SaResult.error();
+ };
+
+ /**
+ * SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
+ */
+ public CheckTicketAppendDataFunction checkTicketAppendData = (loginId, result) -> {
+ return result;
+ };
+
+
// get set
/**
@@ -165,14 +184,14 @@ public class SaSsoServerConfig implements Serializable {
}
/**
- * @return 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
+ * @return 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket) (匿名 client 使用)
*/
public String getAllowUrl() {
return allowUrl;
}
/**
- * @param allowUrl 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
+ * @param allowUrl 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket) (匿名 client 使用)
* @return 对象自身
*/
public SaSsoServerConfig setAllowUrl(String allowUrl) {
@@ -217,22 +236,6 @@ public class SaSsoServerConfig implements Serializable {
return this;
}
- /**
- * @return isHttp 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、获取userinfo)
- */
- public Boolean getIsHttp() {
- return isHttp;
- }
-
- /**
- * @param isHttp 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、获取userinfo)
- * @return 对象自身
- */
- public SaSsoServerConfig setIsHttp(Boolean isHttp) {
- this.isHttp = isHttp;
- return this;
- }
-
/**
* @return 是否在每次下发 ticket 时,自动续期 token 的有效期(根据全局 timeout 值)
*/
@@ -250,14 +253,14 @@ public class SaSsoServerConfig implements Serializable {
}
/**
- * @return maxLoginClient 在 Access-Session 上记录 Client 信息的最高数量(-1=无限),超过此值将进行自动清退处理,先进先出
+ * @return maxLoginClient 在 Account-Session 上记录 Client 信息的最高数量(-1=无限),超过此值将进行自动清退处理,先进先出
*/
public int getMaxRegClient() {
return maxRegClient;
}
/**
- * @param maxRegClient 在 Access-Session 上记录 Client 信息的最高数量(-1=无限),超过此值将进行自动清退处理,先进先出
+ * @param maxRegClient 在 Account-Session 上记录 Client 信息的最高数量(-1=无限),超过此值将进行自动清退处理,先进先出
* @return 对象自身
*/
public SaSsoServerConfig setMaxRegClient(int maxRegClient) {
@@ -304,7 +307,7 @@ public class SaSsoServerConfig implements Serializable {
}
/**
- * 获取 API 调用签名秘钥
+ * 获取 API 调用签名秘钥 (全局默认 + 匿名 client 使用)
*
* @return /
*/
@@ -313,7 +316,7 @@ public class SaSsoServerConfig implements Serializable {
}
/**
- * 设置 API 调用签名秘钥
+ * 设置 API 调用签名秘钥 (全局默认 + 匿名 client 使用)
*
* @param secretKey /
* @return 对象自身
@@ -351,7 +354,6 @@ public class SaSsoServerConfig implements Serializable {
+ ", allowUrl=" + allowUrl
+ ", homeRoute=" + homeRoute
+ ", isSlo=" + isSlo
- + ", isHttp=" + isHttp
+ ", autoRenewTimeout=" + autoRenewTimeout
+ ", maxRegClient=" + maxRegClient
+ ", isCheckSign=" + isCheckSign
@@ -362,107 +364,4 @@ public class SaSsoServerConfig implements Serializable {
}
- // -------------------- 所有回调函数 --------------------
-
-
- /**
- * SSO-Server端:未登录时返回的View
- */
- public NotLoginViewFunction notLoginView = () -> {
- return "当前会话在SSO-Server认证中心尚未登录(当前未配置登录视图)";
- };
-
- /**
- * SSO-Server端:登录函数
- */
- public DoLoginHandleFunction doLoginHandle = (name, pwd) -> {
- return SaResult.error();
- };
-
- /**
- * SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
- */
- public CheckTicketAppendDataFunction checkTicketAppendData = (loginId, result) -> {
- return result;
- };
-
- /**
- * SSO-Server端:发送Http请求的处理函数
- */
- public SendHttpFunction sendHttp = url -> {
- throw new SaSsoException("请配置 Http 请求处理器").setCode(SaSsoErrorCode.CODE_30010);
- };
-
- /**
- * 获取 SSO-Server端:未登录时返回的View
- *
- * @return notLoginView SSO-Server端:未登录时返回的View
- */
- public NotLoginViewFunction getNotLoginView() {
- return this.notLoginView;
- }
-
- /**
- * 设置 SSO-Server端:未登录时返回的View
- *
- * @param notLoginView SSO-Server端:未登录时返回的View
- */
- public void setNotLoginView(NotLoginViewFunction notLoginView) {
- this.notLoginView = notLoginView;
- }
-
- /**
- * 获取 SSO-Server端:登录函数
- *
- * @return doLoginHandle SSO-Server端:登录函数
- */
- public DoLoginHandleFunction getDoLoginHandle() {
- return this.doLoginHandle;
- }
-
- /**
- * 设置 SSO-Server端:登录函数
- *
- * @param doLoginHandle SSO-Server端:登录函数
- */
- public void setDoLoginHandle(DoLoginHandleFunction doLoginHandle) {
- this.doLoginHandle = doLoginHandle;
- }
-
- /**
- * 获取 SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
- *
- * @return checkTicketAppendData SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
- */
- public CheckTicketAppendDataFunction getCheckTicketAppendData() {
- return this.checkTicketAppendData;
- }
-
- /**
- * 设置 SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
- *
- * @param checkTicketAppendData SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
- */
- public void setCheckTicketAppendData(CheckTicketAppendDataFunction checkTicketAppendData) {
- this.checkTicketAppendData = checkTicketAppendData;
- }
-
- /**
- * 获取 SSO-Server端:发送Http请求的处理函数
- *
- * @return sendHttp SSO-Server端:发送Http请求的处理函数
- */
- public SendHttpFunction getSendHttp() {
- return this.sendHttp;
- }
-
- /**
- * 设置 SSO-Server端:发送Http请求的处理函数
- *
- * @param sendHttp SSO-Server端:发送Http请求的处理函数
- */
- public void setSendHttp(SendHttpFunction sendHttp) {
- this.sendHttp = sendHttp;
- }
-
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java
index 49b67781..e1bb6fe5 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java
@@ -68,4 +68,13 @@ public interface SaSsoErrorCode {
/** 无效的 allow-url 配置 */
int CODE_30015 = 30015;
+ /** 未能找到指定类型的消息处理器 */
+ int CODE_30021 = 30021;
+
+ /** 消息类型不能为空 */
+ int CODE_30022 = 30022;
+
+ /** 无效的消息推送地址 */
+ int CODE_30023 = 30023;
+
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessage.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessage.java
new file mode 100644
index 00000000..41098682
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessage.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sso.message;
+
+
+import cn.dev33.satoken.application.SaSetValueInterface;
+import cn.dev33.satoken.sso.error.SaSsoErrorCode;
+import cn.dev33.satoken.sso.exception.SaSsoException;
+import cn.dev33.satoken.util.SaFoxUtil;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Sa-Token SSO 消息 Model
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public class SaSsoMessage extends LinkedHashMap implements SaSetValueInterface, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * KEY:TYPE
+ */
+ public static final String MSG_TYPE = "msg_type";
+
+ public SaSsoMessage() {
+
+ }
+
+ /**
+ * 构造函数
+ * @param type 消息类型
+ */
+ public SaSsoMessage(String type) {
+ setType(type);
+ }
+
+ /**
+ * 构造函数
+ * @param map 消息参数
+ */
+ public SaSsoMessage(Map map) {
+ this.putAll(map);
+ }
+
+ /**
+ * 获取消息类型
+ * @return /
+ */
+ public String getType() {
+ return getString(MSG_TYPE);
+ }
+
+ /**
+ * 设置消息类型
+ * @param type /
+ * @return /
+ */
+ public SaSsoMessage setType(String type) {
+ return set(MSG_TYPE, type);
+ }
+
+ /**
+ * 校验消息类型
+ */
+ public void checkType() {
+ if(SaFoxUtil.isEmpty(getString(MSG_TYPE))) {
+ throw new SaSsoException("消息类型不可为空").setCode(SaSsoErrorCode.CODE_30022);
+ }
+ }
+
+ // -----------
+
+ @Override
+ public Object get(String key) {
+ return super.get(key);
+ }
+
+ @Override
+ public SaSsoMessage set(String key, Object value) {
+ super.put(key, value);
+ return this;
+ }
+
+ @Override
+ public SaSsoMessage delete(String key) {
+ super.remove(key);
+ return this;
+ }
+
+}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessageHolder.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessageHolder.java
new file mode 100644
index 00000000..0b68cde7
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/SaSsoMessageHolder.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sso.message;
+
+
+import cn.dev33.satoken.sso.error.SaSsoErrorCode;
+import cn.dev33.satoken.sso.exception.SaSsoException;
+import cn.dev33.satoken.sso.message.handle.SaSsoMessageHandle;
+import cn.dev33.satoken.sso.template.SaSsoTemplate;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Sa-Token SSO 消息处理器持有者
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public class SaSsoMessageHolder {
+
+ /**
+ * 所有消息处理器的集合
+ */
+ public final Map messageHandleMap = new LinkedHashMap<>();
+
+ /**
+ * 判断是否具有指定类型的消息处理器
+ *
+ * @param type 消息类型
+ * @return /
+ */
+ public boolean hasHandle(String type) {
+ return messageHandleMap.containsKey(type);
+ }
+
+ /**
+ * 删除指定类型的消息处理器
+ *
+ * @param type 消息类型
+ */
+ public SaSsoMessageHolder removeHandle(String type) {
+ messageHandleMap.remove(type);
+ return this;
+ }
+
+ /**
+ * 添加指定类型的消息处理器
+ *
+ * @param handle /
+ */
+ public SaSsoMessageHolder addHandle(SaSsoMessageHandle handle) {
+ messageHandleMap.put(handle.getHandlerType(), handle);
+ return this;
+ }
+
+ /**
+ * 获取指定类型的消息处理器
+ *
+ * @param type /
+ */
+ public SaSsoMessageHandle getHandle(String type) {
+ return messageHandleMap.get(type);
+ }
+
+ /**
+ * 处理指定消息
+ *
+ * @param ssoTemplate /
+ * @param message /
+ * @return /
+ */
+ public Object handleMessage(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+ SaSsoMessageHandle handle = messageHandleMap.get(message.getType());
+ if(handle == null) {
+ throw new SaSsoException("未能找到消息处理器: " + message.getType()).setCode(SaSsoErrorCode.CODE_30021);
+ }
+ return handle.handle(ssoTemplate, message);
+ }
+
+}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/SaSsoMessageHandle.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/SaSsoMessageHandle.java
new file mode 100644
index 00000000..32944139
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/SaSsoMessageHandle.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sso.message.handle;
+
+
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.template.SaSsoTemplate;
+
+/**
+ * Sa-Token SSO 消息 处理器
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public interface SaSsoMessageHandle {
+
+ /**
+ * 获取所要处理的消息类型
+ *
+ * @return /
+ */
+ String getHandlerType();
+
+ /**
+ * 执行方法
+ *
+ * @param ssoTemplate /
+ * @param message /
+ * @return /
+ */
+ Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message);
+
+}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/client/SaSsoMessageLogoutCallHandle.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/client/SaSsoMessageLogoutCallHandle.java
new file mode 100644
index 00000000..f728f4af
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/client/SaSsoMessageLogoutCallHandle.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sso.message.handle.client;
+
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.message.handle.SaSsoMessageHandle;
+import cn.dev33.satoken.sso.name.ParamName;
+import cn.dev33.satoken.sso.template.SaSsoClientTemplate;
+import cn.dev33.satoken.sso.template.SaSsoTemplate;
+import cn.dev33.satoken.sso.util.SaSsoConsts;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.util.SaResult;
+
+/**
+ * Sa-Token SSO 消息 处理器 - sso-client 端:处理 单点注销回调 的请求
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public class SaSsoMessageLogoutCallHandle implements SaSsoMessageHandle {
+
+ /**
+ * 获取所要处理的消息类型
+ *
+ * @return /
+ */
+ public String getHandlerType() {
+ return SaSsoConsts.MESSAGE_LOGOUT_CALL;
+ }
+
+ /**
+ * 执行方法
+ *
+ * @param ssoTemplate /
+ * @param message /
+ * @return /
+ */
+ public Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+ SaSsoClientTemplate ssoClientTemplate = (SaSsoClientTemplate) ssoTemplate;
+ if( ! ssoClientTemplate.getClientConfig().getIsSlo()) {
+ return SaResult.error("当前 sso-client 端未开启单点注销功能");
+ }
+
+ // 获取对象
+ SaRequest req = SaHolder.getRequest();
+ StpLogic stpLogic = ssoClientTemplate.getStpLogic();
+ ParamName paramName = ssoClientTemplate.paramName;
+
+ // 获取参数
+ String loginId = req.getParamNotNull(paramName.loginId);
+
+ // 注销当前应用端会话
+ stpLogic.logout(loginId);
+
+ // 响应
+ return SaResult.ok("单点注销回调成功");
+ }
+
+}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/server/SaSsoMessageCheckTicketHandle.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/server/SaSsoMessageCheckTicketHandle.java
new file mode 100644
index 00000000..22ae41c0
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/server/SaSsoMessageCheckTicketHandle.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sso.message.handle.server;
+
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.sso.SaSsoManager;
+import cn.dev33.satoken.sso.config.SaSsoServerConfig;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.message.handle.SaSsoMessageHandle;
+import cn.dev33.satoken.sso.name.ParamName;
+import cn.dev33.satoken.sso.template.SaSsoServerTemplate;
+import cn.dev33.satoken.sso.template.SaSsoTemplate;
+import cn.dev33.satoken.sso.util.SaSsoConsts;
+import cn.dev33.satoken.util.SaFoxUtil;
+import cn.dev33.satoken.util.SaResult;
+
+/**
+ * Sa-Token SSO 消息 处理器 - sso-server 端:处理校验 ticket 的请求
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public class SaSsoMessageCheckTicketHandle implements SaSsoMessageHandle {
+
+ /**
+ * 获取所要处理的消息类型
+ *
+ * @return /
+ */
+ public String getHandlerType() {
+ return SaSsoConsts.MESSAGE_CHECK_TICKET;
+ }
+
+ /**
+ * 执行方法
+ *
+ * @param ssoTemplate /
+ * @param message /
+ * @return /
+ */
+ public Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+ SaSsoServerTemplate ssoServerTemplate = (SaSsoServerTemplate) ssoTemplate;
+ ParamName paramName = ssoServerTemplate.paramName;
+
+ // 1、获取参数
+ SaRequest req = SaHolder.getRequest();
+ SaSsoServerConfig ssoServerConfig = ssoServerTemplate.getServerConfig();
+ String client = req.getParam(paramName.client);
+ String ticket = req.getParamNotNull(paramName.ticket);
+ String sloCallback = req.getParam(paramName.ssoLogoutCall);
+
+ // 2、校验提供的client是否为非法字符
+ if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) {
+ return SaResult.error("无效 client 标识:" + client);
+ }
+
+ // 3、校验签名
+// if(ssoServerConfig.getIsCheckSign()) {
+// ssoServerTemplate.getSignTemplate(client).checkRequest(req, paramName.client, paramName.ticket, paramName.ssoLogoutCall);
+// } else {
+// SaSsoManager.printNoCheckSignWarningByRuntime();
+// }
+
+ // 4、校验ticket,获取 loginId
+ Object loginId = ssoServerTemplate.checkTicket(ticket, client);
+ if(SaFoxUtil.isEmpty(loginId)) {
+ return SaResult.error("无效ticket:" + ticket);
+ }
+
+ // 5、注册此客户端的单点注销回调URL
+ ssoServerTemplate.registerSloCallbackUrl(loginId, client, sloCallback);
+
+ // 6、给 client 端响应结果
+ long remainSessionTimeout = ssoServerTemplate.getStpLogic().getSessionTimeoutByLoginId(loginId);
+ SaResult result = SaResult.data(loginId).set(paramName.remainSessionTimeout, remainSessionTimeout);
+ result = ssoServerConfig.checkTicketAppendData.apply(loginId, result);
+ return result;
+ }
+
+}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/server/SaSsoMessageSignoutHandle.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/server/SaSsoMessageSignoutHandle.java
new file mode 100644
index 00000000..43b83d57
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/message/handle/server/SaSsoMessageSignoutHandle.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sso.message.handle.server;
+
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.message.handle.SaSsoMessageHandle;
+import cn.dev33.satoken.sso.name.ParamName;
+import cn.dev33.satoken.sso.template.SaSsoServerTemplate;
+import cn.dev33.satoken.sso.template.SaSsoTemplate;
+import cn.dev33.satoken.sso.util.SaSsoConsts;
+import cn.dev33.satoken.util.SaResult;
+
+/**
+ * Sa-Token SSO 消息 处理器 - sso-server 端:处理 单点注销 的请求
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public class SaSsoMessageSignoutHandle implements SaSsoMessageHandle {
+
+ /**
+ * 获取所要处理的消息类型
+ *
+ * @return /
+ */
+ public String getHandlerType() {
+ return SaSsoConsts.MESSAGE_SIGNOUT;
+ }
+
+ /**
+ * 执行方法
+ *
+ * @param ssoTemplate /
+ * @param message /
+ * @return /
+ */
+ public Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+ SaSsoServerTemplate ssoServerTemplate = (SaSsoServerTemplate) ssoTemplate;
+ ParamName paramName = ssoServerTemplate.paramName;
+
+ if( ! ssoServerTemplate.getServerConfig().getIsSlo()) {
+ return SaResult.error("当前 sso-server 端未开启单点注销功能");
+ }
+
+ // 获取参数
+ SaRequest req = SaHolder.getRequest();
+ String loginId = req.getParam(paramName.loginId);
+
+ // step.2 单点注销
+ ssoServerTemplate.ssoLogout(loginId);
+
+ // 响应
+ return SaResult.ok();
+ }
+
+}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java
index 8d2545fb..7d877d86 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java
@@ -32,6 +32,9 @@ public class ApiName {
/** SSO-Server端:校验ticket 获取账号id */
public String ssoCheckTicket = "/sso/checkTicket";
+ /** SSO-Server端:接受推送消息 */
+ public String ssoPushS = "/sso/pushS";
+
/** SSO-Server端:获取userinfo */
public String ssoUserinfo = "/sso/userinfo";
@@ -46,7 +49,10 @@ public class ApiName {
/** SSO-Client端:单点注销的回调 */
public String ssoLogoutCall = "/sso/logoutCall";
-
+
+ /** SSO-Client端:接受推送消息 */
+ public String ssoPushC = "/sso/pushC";
+
/**
* 批量修改path,新增固定前缀
* @param prefix 示例值:/sso-user、/sso-admin
@@ -56,10 +62,12 @@ public class ApiName {
this.ssoAuth = prefix + this.ssoAuth;
this.ssoDoLogin = prefix + this.ssoDoLogin;
this.ssoCheckTicket = prefix + this.ssoCheckTicket;
+ this.ssoPushS = prefix + this.ssoPushS;
this.ssoUserinfo = prefix + this.ssoUserinfo;
this.ssoSignout = prefix + this.ssoSignout;
this.ssoLogin = prefix + this.ssoLogin;
this.ssoLogout = prefix + this.ssoLogout;
+ this.ssoPushC = prefix + this.ssoPushC;
this.ssoLogoutCall = prefix + this.ssoLogoutCall;
return this;
}
@@ -74,21 +82,30 @@ public class ApiName {
this.ssoAuth = this.ssoAuth.replaceFirst(oldPrefix, prefix);
this.ssoDoLogin = this.ssoDoLogin.replaceFirst(oldPrefix, prefix);
this.ssoCheckTicket = this.ssoCheckTicket.replaceFirst(oldPrefix, prefix);
+ this.ssoPushS = this.ssoPushS.replaceFirst(oldPrefix, prefix);
this.ssoUserinfo = this.ssoUserinfo.replaceFirst(oldPrefix, prefix);
this.ssoSignout = this.ssoSignout.replaceFirst(oldPrefix, prefix);
this.ssoLogin = this.ssoLogin.replaceFirst(oldPrefix, prefix);
this.ssoLogout = this.ssoLogout.replaceFirst(oldPrefix, prefix);
+ this.ssoPushC = this.ssoPushC.replaceFirst(oldPrefix, prefix);
this.ssoLogoutCall = this.ssoLogoutCall.replaceFirst(oldPrefix, prefix);
return this;
}
-
@Override
public String toString() {
- return "ApiName [ssoAuth=" + ssoAuth + ", ssoDoLogin=" + ssoDoLogin + ", ssoCheckTicket=" + ssoCheckTicket
- + ", ssoUserinfo=" + ssoUserinfo + ", ssoSignout=" + ssoSignout + ", ssoLogin=" + ssoLogin
- + ", ssoLogout=" + ssoLogout + ", ssoLogoutCall=" + ssoLogoutCall + "]";
+ return "ApiName{" +
+ "ssoAuth='" + ssoAuth + '\'' +
+ ", ssoDoLogin='" + ssoDoLogin + '\'' +
+ ", ssoCheckTicket='" + ssoCheckTicket + '\'' +
+ ", ssoPushS='" + ssoPushS + '\'' +
+ ", ssoUserinfo='" + ssoUserinfo + '\'' +
+ ", ssoSignout='" + ssoSignout + '\'' +
+ ", ssoLogin='" + ssoLogin + '\'' +
+ ", ssoLogout='" + ssoLogout + '\'' +
+ ", ssoLogoutCall='" + ssoLogoutCall + '\'' +
+ ", ssoPushC='" + ssoPushC + '\'' +
+ '}';
}
-
}
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 672415c5..aa78a3ab 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
@@ -22,6 +22,7 @@ import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
import cn.dev33.satoken.sso.model.SaCheckTicketResult;
import cn.dev33.satoken.sso.name.ApiName;
import cn.dev33.satoken.sso.name.ParamName;
@@ -31,6 +32,8 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
+import java.util.Map;
+
/**
* SSO 请求处理器 (Client端)
*
@@ -74,8 +77,13 @@ public class SaSsoClientProcessor {
return ssoLogout();
}
+ // ---------- SSO-Client端:接收消息推送
+ if(req.isPath(apiName.ssoPushC)) {
+ return ssoPushC();
+ }
+
// ---------- SSO-Client端:单点注销的回调 [模式三]
- if(req.isPath(apiName.ssoLogoutCall) && cfg.getIsSlo() && cfg.getIsHttp()) {
+ if(req.isPath(apiName.ssoLogoutCall) && cfg.getRegLogoutCall()) {
return ssoLogoutCall();
}
@@ -154,6 +162,27 @@ public class SaSsoClientProcessor {
return SaSsoConsts.NOT_HANDLE;
}
+ /**
+ * SSO-Client端:接收推送消息
+ *
+ * @return 处理结果
+ */
+ public Object ssoPushC() {
+ SaSsoClientConfig ssoClientConfig = ssoClientTemplate.getClientConfig();
+
+ // 1、校验签名
+ Map paramMap = SaHolder.getRequest().getParamMap();
+ if(ssoClientConfig.getIsCheckSign()) {
+ ssoClientTemplate.getSignTemplate(ssoClientConfig.getClient()).checkParamMap(paramMap);
+ } else {
+ SaSsoManager.printNoCheckSignWarningByRuntime();
+ }
+
+ // 2、处理消息
+ SaSsoMessage message = new SaSsoMessage(paramMap);
+ return ssoClientTemplate.handleMessage(message);
+ }
+
/**
* SSO-Client端:单点注销 [模式二]
* @return 处理结果
@@ -189,8 +218,8 @@ public class SaSsoClientProcessor {
}
// 调用 sso-server 认证中心单点注销API
- String url = ssoClientTemplate.buildSloUrl(stpLogic.getLoginId());
- SaResult result = ssoClientTemplate.request(url);
+ SaSsoMessage message = ssoClientTemplate.buildSloMessage(stpLogic.getLoginId());
+ SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
// 校验响应状态码
if(result.getCode() != null && SaResult.CODE_SUCCESS == result.getCode()) {
@@ -224,8 +253,7 @@ public class SaSsoClientProcessor {
// 校验参数签名
if(ssoConfig.getIsCheckSign()) {
- ssoClientTemplate.getSignTemplate(ssoConfig.getClient()).
- checkRequest(req, paramName.loginId, paramName.client, paramName.autoLogout);
+ ssoClientTemplate.getSignTemplate(ssoConfig.getClient()).checkRequest(req, paramName.loginId, paramName.client, paramName.autoLogout);
} else {
SaSsoManager.printNoCheckSignWarningByRuntime();
}
@@ -256,7 +284,7 @@ public class SaSsoClientProcessor {
// 计算当前 sso-client 的单点注销回调地址
String ssoLogoutCall = null;
- if(cfg.getIsSlo()) {
+ if(cfg.getRegLogoutCall()) {
// 如果配置了回调地址,就使用配置的值:
if(SaFoxUtil.isNotEmpty(cfg.getCurrSsoLogoutCall())) {
ssoLogoutCall = cfg.getCurrSsoLogoutCall();
@@ -270,11 +298,9 @@ public class SaSsoClientProcessor {
}
}
- // 构建请求URL
- String checkUrl = ssoClientTemplate.buildCheckTicketUrl(ticket, ssoLogoutCall);
-
// 发起请求
- SaResult result = ssoClientTemplate.request(checkUrl);
+ SaSsoMessage message = ssoClientTemplate.buildCheckTicketMessage(ticket, ssoLogoutCall);
+ SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
// 校验
if(result.getCode() != null && result.getCode() == SaResult.CODE_SUCCESS) {
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java
index 168cecc3..f8e97c22 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java
@@ -22,6 +22,7 @@ import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.sso.config.SaSsoServerConfig;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
import cn.dev33.satoken.sso.name.ApiName;
import cn.dev33.satoken.sso.name.ParamName;
import cn.dev33.satoken.sso.template.SaSsoServerTemplate;
@@ -30,6 +31,8 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
+import java.util.Map;
+
/**
* SSO 请求处理器 (Server端)
*
@@ -63,26 +66,26 @@ public class SaSsoServerProcessor {
// ------------------ 路由分发 ------------------
- // ---------- SSO-Server端:授权地址
+ // sso-server:授权地址
if(req.isPath(apiName.ssoAuth)) {
return ssoAuth();
}
- // ---------- SSO-Server端:RestAPI 登录接口
+ // sso-server:RestAPI 登录接口
if(req.isPath(apiName.ssoDoLogin)) {
return ssoDoLogin();
}
- // ---------- SSO-Server端:校验ticket 获取账号id
- if(req.isPath(apiName.ssoCheckTicket) && cfg.getIsHttp()) {
- return ssoCheckTicket();
- }
-
- // ---------- SSO-Server端:单点注销
+ // sso-server:单点注销
if(req.isPath(apiName.ssoSignout)) {
return ssoSignout();
}
+ // sso-server:接收推送消息
+ if(req.isPath(apiName.ssoPushS)) {
+ return ssoPush();
+ }
+
// 默认返回
return SaSsoConsts.NOT_HANDLE;
}
@@ -162,78 +165,11 @@ public class SaSsoServerProcessor {
return cfg.doLoginHandle.apply(req.getParam(paramName.name), req.getParam(paramName.pwd));
}
- /**
- * SSO-Server端:校验ticket 获取账号id [模式三]
- * @return 处理结果
- */
- public Object ssoCheckTicket() {
- ParamName paramName = ssoServerTemplate.paramName;
-
- // 1、获取参数
- SaRequest req = SaHolder.getRequest();
- SaSsoServerConfig ssoServerConfig = ssoServerTemplate.getServerConfig();
- String client = req.getParam(paramName.client);
- String ticket = req.getParamNotNull(paramName.ticket);
- String sloCallback = req.getParam(paramName.ssoLogoutCall);
-
- // 2、校验提供的client是否为非法字符
- if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) {
- return SaResult.error("无效 client 标识:" + client);
- }
-
- // 3、校验签名
- if(ssoServerConfig.getIsCheckSign()) {
- ssoServerTemplate.getSignTemplate(client).checkRequest(req,
- paramName.client, paramName.ticket, paramName.ssoLogoutCall);
- } else {
- SaSsoManager.printNoCheckSignWarningByRuntime();
- }
-
- // 4、校验ticket,获取 loginId
- Object loginId = ssoServerTemplate.checkTicket(ticket, client);
- if(SaFoxUtil.isEmpty(loginId)) {
- return SaResult.error("无效ticket:" + ticket);
- }
-
- // 5、注册此客户端的单点注销回调URL
- ssoServerTemplate.registerSloCallbackUrl(loginId, client, sloCallback);
-
- // 6、给 client 端响应结果
- long remainSessionTimeout = ssoServerTemplate.getStpLogic().getSessionTimeoutByLoginId(loginId);
- SaResult result = SaResult.data(loginId).set(paramName.remainSessionTimeout, remainSessionTimeout);
- result = ssoServerConfig.checkTicketAppendData.apply(loginId, result);
- return result;
- }
-
/**
* SSO-Server端:单点注销
* @return 处理结果
*/
public Object ssoSignout() {
- // 获取对象
- SaRequest req = SaHolder.getRequest();
- SaSsoServerConfig cfg = ssoServerTemplate.getServerConfig();
- ParamName paramName = ssoServerTemplate.paramName;
-
- // SSO-Server端:单点注销 [用户访问式] (不带loginId参数)
- if(cfg.getIsSlo() && ! req.hasParam(paramName.loginId)) {
- return ssoSignoutByUserVisit();
- }
-
- // SSO-Server端:单点注销 [Client调用式] (带loginId参数)
- if(cfg.getIsSlo() && req.hasParam(paramName.loginId)) {
- return ssoSignoutByClientHttp();
- }
-
- // 默认返回
- return SaSsoConsts.NOT_HANDLE;
- }
-
- /**
- * SSO-Server端:单点注销 [用户访问式]
- * @return 处理结果
- */
- public Object ssoSignoutByUserVisit() {
// 获取对象
SaRequest req = SaHolder.getRequest();
SaResponse res = SaHolder.getResponse();
@@ -245,43 +181,41 @@ public class SaSsoServerProcessor {
}
// 完成
- return ssoLogoutBack(req, res);
+ return SaSsoProcessorHelper.ssoLogoutBack(req, res, ssoServerTemplate.paramName);
}
/**
- * SSO-Server端:单点注销 [Client调用式]
+ * SSO-Server端:接收推送消息
+ *
* @return 处理结果
*/
- public Object ssoSignoutByClientHttp() {
+ public Object ssoPush() {
ParamName paramName = ssoServerTemplate.paramName;
+ SaSsoServerConfig ssoServerConfig = ssoServerTemplate.getServerConfig();
- // 获取参数
+ // 1、获取参数
SaRequest req = SaHolder.getRequest();
- String loginId = req.getParam(paramName.loginId);
String client = req.getParam(paramName.client);
- // step.1 校验签名
- if(ssoServerTemplate.getServerConfig().getIsCheckSign()) {
- ssoServerTemplate.getSignTemplate(client).checkRequest(req, paramName.client, paramName.loginId);
+ // 2、校验提供的client是否为非法字符
+ if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) {
+ return SaResult.error("无效 client 标识:" + client);
+ }
+
+ // 3、校验签名
+ Map paramMap = req.getParamMap();
+ if(ssoServerConfig.getIsCheckSign()) {
+ ssoServerTemplate.getSignTemplate(client).checkParamMap(paramMap);
} else {
SaSsoManager.printNoCheckSignWarningByRuntime();
}
- // step.2 单点注销
- ssoServerTemplate.ssoLogout(loginId);
-
- // 响应
- return SaResult.ok();
+ // 处理消息
+ SaSsoMessage message = new SaSsoMessage(paramMap);
+ if( ! ssoServerTemplate.messageHolder.hasHandle(message.getType())) {
+ return SaResult.error("未能找到消息处理器: " + message.getType());
+ }
+ return ssoServerTemplate.handleMessage(message);
}
- /**
- * 封装:单点注销成功后返回结果
- * @param req SaRequest对象
- * @param res SaResponse对象
- * @return 返回结果
- */
- public Object ssoLogoutBack(SaRequest req, SaResponse res) {
- return SaSsoProcessorHelper.ssoLogoutBack(req, res, ssoServerTemplate.paramName);
- }
-
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientTemplate.java
index bbfe80d4..be87ade0 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientTemplate.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientTemplate.java
@@ -22,11 +22,13 @@ import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.message.handle.client.SaSsoMessageLogoutCallHandle;
+import cn.dev33.satoken.sso.util.SaSsoConsts;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
import java.util.Map;
-import java.util.TreeMap;
/**
* Sa-Token SSO 模板方法类 (Client端)
@@ -36,12 +38,8 @@ import java.util.TreeMap;
*/
public class SaSsoClientTemplate extends SaSsoTemplate {
- /**
- * 获取底层使用的SsoClient配置对象
- * @return /
- */
- public SaSsoClientConfig getClientConfig() {
- return SaSsoManager.getClientConfig();
+ public SaSsoClientTemplate() {
+ super.messageHolder.addHandle(new SaSsoMessageLogoutCallHandle());
}
@@ -66,7 +64,7 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
*/
public Object getData(String path, Map paramMap) {
String url = buildCustomPathUrl(path, paramMap);
- return getClientConfig().sendHttp.apply(url);
+ return request(url);
}
// ---------------------- 构建URL ----------------------
@@ -108,56 +106,6 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
return SaFoxUtil.joinParam(serverUrl, paramName.redirect, clientLoginUrl);
}
- /**
- * 构建URL:校验ticket的URL
- * 在模式三下,Client端拿到Ticket后根据此地址向Server端发送请求,获取账号id
- * @param ticket ticket码
- * @param ssoLogoutCallUrl 单点注销时的回调URL
- * @return 构建完毕的URL
- */
- public String buildCheckTicketUrl(String ticket, String ssoLogoutCallUrl) {
-
- SaSsoClientConfig ssoConfig = getClientConfig();
-
- // 1、url
- String url = ssoConfig.splicingCheckTicketUrl();
-
- // 2、参数:client、ticket、ssoLogoutCall
- Map paramMap = new TreeMap<>();
- paramMap.put(paramName.ticket, ticket);
- paramMap.put(paramName.client, ssoConfig.getClient());
- paramMap.put(paramName.ssoLogoutCall, ssoLogoutCallUrl);
-
- // 追加签名参数,并序列化为kv字符串
- String signParamStr = getSignTemplate(ssoConfig.getClient()).addSignParamsAndJoin(paramMap);
-
- // 3、拼接
- return SaFoxUtil.joinParam(url, signParamStr);
- }
-
- /**
- * 构建URL:单点注销URL
- * @param loginId 要注销的账号id
- * @return 单点注销URL
- */
- public String buildSloUrl(Object loginId) {
- // 获取所需对象
- SaSsoClientConfig ssoConfig = getClientConfig();
- String url = ssoConfig.splicingSloUrl();
- String currClient = ssoConfig.getClient();
-
- // 组织请求参数
- Map paramMap = new TreeMap<>();
- paramMap.put(paramName.loginId, loginId);
- paramMap.put(paramName.client, currClient);
-
- // 追加签名参数,并序列化为kv字符串
- String signParamsStr = getSignTemplate(currClient).addSignParamsAndJoin(paramMap);
-
- // 拼接到 url 上
- return SaFoxUtil.joinParam(url, signParamsStr);
- }
-
/**
* 构建URL:Server端 getData 地址,带签名等参数
* @param paramMap 查询参数
@@ -181,7 +129,7 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
String url = path;
if( ! url.startsWith("http") ) {
String serverUrl = ssoConfig.getServerUrl();
- SaSsoException.notEmpty(serverUrl, "请先配置 sa-token.sso.server-url 地址", SaSsoErrorCode.CODE_30012);
+ SaSsoException.notEmpty(serverUrl, "请先配置 sa-token.sso-client.server-url 地址", SaSsoErrorCode.CODE_30012);
url = SaFoxUtil.spliceTwoUrl(serverUrl, path);
}
@@ -193,6 +141,86 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
return SaFoxUtil.joinParam(url, signParamsStr);
}
+ /**
+ * 构建消息:校验 ticket
+ *
+ * @param ticket ticket码
+ * @param ssoLogoutCallUrl 单点注销时的回调URL
+ * @return 构建完毕的URL
+ */
+ public SaSsoMessage buildCheckTicketMessage(String ticket, String ssoLogoutCallUrl) {
+ SaSsoClientConfig ssoConfig = getClientConfig();
+ SaSsoMessage message = new SaSsoMessage();
+ message.setType(SaSsoConsts.MESSAGE_CHECK_TICKET);
+ message.set(paramName.client, ssoConfig.getClient());
+ message.set(paramName.ticket, ticket);
+ message.set(paramName.ssoLogoutCall, ssoLogoutCallUrl);
+ return message;
+ }
+
+ /**
+ * 构建消息:单点注销
+ * @param loginId 要注销的账号 id
+ * @return 单点注销URL
+ */
+ public SaSsoMessage buildSloMessage(Object loginId) {
+ SaSsoClientConfig ssoConfig = getClientConfig();
+ SaSsoMessage message = new SaSsoMessage();
+ message.setType(SaSsoConsts.MESSAGE_SIGNOUT);
+ message.set(paramName.client, ssoConfig.getClient());
+ message.set(paramName.loginId, loginId);
+ return message;
+ }
+
+
+ // ------------------- 消息推送 -------------------
+
+ /**
+ * 向 sso-server 推送消息
+ *
+ * @param message /
+ * @return /
+ */
+ public String pushMessage(SaSsoMessage message) {
+ SaSsoClientConfig ssoConfig = getClientConfig();
+
+ // 拼接 push-url 地址
+ String pushUrl = ssoConfig.splicingPushUrl();
+ SaSsoException.notTrue(! SaFoxUtil.isUrl(pushUrl), "无效 push-url 地址:" + pushUrl, SaSsoErrorCode.CODE_30023);
+
+ // 组织参数
+ message.set(paramName.client, ssoConfig.getClient());
+ message.checkType();
+ String paramsStr = getSignTemplate(ssoConfig.getClient()).addSignParamsAndJoin(message);
+
+ // 发起请求
+ String finalUrl = SaFoxUtil.joinParam(pushUrl, paramsStr);
+ return request(finalUrl);
+ }
+
+ /**
+ * 向 sso-server 推送消息,并将返回值转为 SaResult
+ *
+ * @param message /
+ * @return /
+ */
+ public SaResult pushMessageAsSaResult(SaSsoMessage message) {
+ String res = pushMessage(message);
+ Map map = SaManager.getSaJsonTemplate().jsonToMap(res);
+ return new SaResult(map);
+ }
+
+
+ // ------------------- Bean 对象获取 -------------------
+
+ /**
+ * 获取底层使用的SsoClient配置对象
+ * @return /
+ */
+ public SaSsoClientConfig getClientConfig() {
+ return SaSsoManager.getClientConfig();
+ }
+
/**
* 获取底层使用的 API 签名对象
* @param client 指定客户端标识,填 null 代表获取默认的
@@ -212,18 +240,4 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
return new SaSignTemplate(signConfig);
}
-
- // ------------------- 发起请求 -------------------
-
- /**
- * 发出请求,并返回 SaResult 结果
- * @param url 请求地址
- * @return 返回的结果
- */
- public SaResult request(String url) {
- String body = getClientConfig().sendHttp.apply(url);
- Map map = SaManager.getSaJsonTemplate().jsonToMap(body);
- return new SaResult(map);
- }
-
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java
index f24f5caf..b85e2c61 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java
@@ -17,7 +17,6 @@ package cn.dev33.satoken.sso.template;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.config.SaSignConfig;
-import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.sign.SaSignTemplate;
import cn.dev33.satoken.sso.SaSsoManager;
@@ -25,10 +24,14 @@ import cn.dev33.satoken.sso.config.SaSsoClientModel;
import cn.dev33.satoken.sso.config.SaSsoServerConfig;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.message.handle.server.SaSsoMessageCheckTicketHandle;
+import cn.dev33.satoken.sso.message.handle.server.SaSsoMessageSignoutHandle;
import cn.dev33.satoken.sso.model.SaSsoClientInfo;
import cn.dev33.satoken.sso.util.SaSsoConsts;
import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.util.SaFoxUtil;
+import cn.dev33.satoken.util.SaResult;
import java.util.*;
@@ -40,12 +43,9 @@ import java.util.*;
*/
public class SaSsoServerTemplate extends SaSsoTemplate {
- /**
- * 获取底层使用的SsoServer配置对象
- * @return /
- */
- public SaSsoServerConfig getServerConfig() {
- return SaSsoManager.getServerConfig();
+ public SaSsoServerTemplate() {
+ super.messageHolder.addHandle(new SaSsoMessageCheckTicketHandle());
+ super.messageHolder.addHandle(new SaSsoMessageSignoutHandle());
}
// ---------------------- Ticket 操作 ----------------------
@@ -165,7 +165,6 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
}
//
-
/**
* 根据 账号id 创建一个 Ticket码
* @param loginId 账号id
@@ -217,8 +216,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
} else {
// 开始详细比对
if(SaFoxUtil.notEquals(client, ticketClient)) {
- throw new SaSsoException("该 ticket 不属于 client=" + client + ", ticket 值: " + ticket)
- .setCode(SaSsoErrorCode.CODE_30011);
+ throw new SaSsoException("该 ticket 不属于 client=" + client + ", ticket 值: " + ticket).setCode(SaSsoErrorCode.CODE_30011);
}
}
@@ -241,19 +239,28 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
return SaFoxUtil.getRandomString(64);
}
+
+ // ---------------------- Client 信息获取 ----------------------
+
/**
- * 获取:所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
+ * 获取所有 Client
+ *
+ * @return /
+ */
+ public List getClients() {
+ Map clients = getServerConfig().getClients();
+ return new ArrayList<>(clients.values());
+ }
+
+ /**
+ * 获取应用信息,无效 client 返回 null
*
* @param client /
* @return /
*/
-// public String getAllowUrl(String client) {
-// if(SaFoxUtil.isEmpty(client)) {
-// return getServerConfig().getAllowUrl();
-// } else {
-// return getClientNotNull(client).getAllowUrl();
-// }
-// }
+ public SaSsoClientModel getClient(String client) {
+ return getServerConfig().getClients().get(client);
+ }
/**
* 获取应用信息,无效 client 则抛出异常
@@ -295,13 +302,70 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
}
/**
- * 获取应用信息,无效 client 返回 null
+ * 获取所有需要接收消息推送的 Client
*
- * @param client /
* @return /
*/
- public SaSsoClientModel getClient(String client) {
- return getServerConfig().getClients().get(client);
+ public List getNeedPushClients() {
+ List list = new ArrayList<>();
+ List clients = getClients();
+ for(SaSsoClientModel scm : clients) {
+ if (scm.isValidNoticeUrl()) {
+ list.add(scm);
+ }
+ }
+ return list;
+ }
+
+
+ // ------------------- 重定向 URL 构建与校验 -------------------
+
+ /**
+ * 构建URL:Server端向Client下放ticket的地址
+ * @param loginId 账号id
+ * @param client 客户端标识
+ * @param redirect Client端提供的重定向地址
+ * @return see note
+ */
+ public String buildRedirectUrl(Object loginId, String client, String redirect) {
+
+ // 校验 重定向地址 是否合法
+ checkRedirectUrl(client, redirect);
+
+ // 删掉 旧Ticket
+ deleteTicket(getTicketValue(loginId));
+
+ // 创建 新Ticket
+ String ticket = createTicket(loginId, client);
+
+ // 构建 授权重定向地址 (Server端 根据此地址向 Client端 下放Ticket)
+ return SaFoxUtil.joinParam(encodeBackParam(redirect), paramName.ticket, ticket);
+ }
+
+ /**
+ * 对url中的back参数进行URL编码, 解决超链接重定向后参数丢失的bug
+ * @param url url
+ * @return 编码过后的url
+ */
+ public String encodeBackParam(String url) {
+
+ // 获取back参数所在位置
+ int index = url.indexOf("?" + paramName.back + "=");
+ if(index == -1) {
+ index = url.indexOf("&" + paramName.back + "=");
+ if(index == -1) {
+ return url;
+ }
+ }
+
+ // 开始编码
+ int length = paramName.back.length() + 2;
+ String back = url.substring(index + length);
+ back = SaFoxUtil.encodeUrl(back);
+
+ // 放回url中
+ url = url.substring(0, index + length) + back;
+ return url;
}
/**
@@ -402,55 +466,11 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
}
}
- // ------------------- SSO -------------------
+
+ // ------------------- 单点注销 -------------------
/**
- * 指定账号单点注销
- * @param loginId 指定账号
- */
- public void ssoLogout(Object loginId) {
-
- // 如果这个账号尚未登录,则无操作
- SaSession session = getStpLogic().getSessionByLoginId(loginId, false);
- if(session == null) {
- return;
- }
-
- // step.1 遍历通知 Client 端注销会话
- List scmList = session.get(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, ArrayList::new);
- scmList.forEach(scm -> {
- notifyClientLogout(loginId, scm, false);
- });
-
- // step.2 Server端注销
- getStpLogic().logout(loginId);
- }
-
- /**
- * 计算下一个 index 值
- * @param scmList /
- * @return /
- */
- public int calcNextIndex(List scmList) {
- // 如果目前还没有任何登录记录,则直接返回0
- if(scmList == null || scmList.isEmpty()) {
- return 0;
- }
- // 获取目前最大的index值
- int maxIndex = scmList.get(scmList.size() - 1).index;
-
- // 如果已经是 int 最大值了,则直接返回0
- if(maxIndex == Integer.MAX_VALUE) {
- return 0;
- }
-
- // 否则返回最大值+1
- maxIndex++;
- return maxIndex;
- }
-
- /**
- * 为指定账号id注册单点注销回调信息(模式三)
+ * 为指定账号 id 注册单点注销回调信息(模式三)
* @param loginId 账号id
* @param client 指定客户端标识,可为null
* @param sloCallbackUrl 单点注销时的回调URL
@@ -487,6 +507,52 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
session.set(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, scmList);
}
+ /**
+ * 计算下一个 index 值
+ * @param scmList /
+ * @return /
+ */
+ public int calcNextIndex(List scmList) {
+ // 如果目前还没有任何登录记录,则直接返回0
+ if(scmList == null || scmList.isEmpty()) {
+ return 0;
+ }
+ // 获取目前最大的index值
+ int maxIndex = scmList.get(scmList.size() - 1).index;
+
+ // 如果已经是 int 最大值了,则直接返回0
+ if(maxIndex == Integer.MAX_VALUE) {
+ return 0;
+ }
+
+ // 否则返回最大值+1
+ maxIndex++;
+ return maxIndex;
+ }
+
+ /**
+ * 指定账号单点注销
+ * @param loginId 指定账号
+ */
+ public void ssoLogout(Object loginId) {
+
+ // 1、消息推送:单点注销
+ pushToAllClientByLogoutCall(loginId);
+
+ // 2、SaSession 挂载的 Client 端注销会话
+ SaSession session = getStpLogic().getSessionByLoginId(loginId, false);
+ if(session == null) {
+ return;
+ }
+ List scmList = session.get(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, ArrayList::new);
+ scmList.forEach(scm -> {
+ notifyClientLogout(loginId, scm, false);
+ });
+
+ // 3、Server 端本身注销
+ getStpLogic().logout(loginId);
+ }
+
/**
* 通知指定账号的指定客户端注销
* @param loginId 指定账号
@@ -500,7 +566,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
return;
}
- // url
+ // 如果此 Client 并没有注册 单点登录 回调地址,则立即返回
String sloCallUrl = scm.getSloCallbackUrl();
if(SaFoxUtil.isEmpty(sloCallUrl)) {
return;
@@ -517,74 +583,102 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
String finalUrl = SaFoxUtil.joinParam(sloCallUrl, signParamsStr);
// 发起请求
- getServerConfig().sendHttp.apply(finalUrl);
+ request(finalUrl);
}
- // ---------------------- 构建URL ----------------------
+
+ // ------------------- 消息推送 -------------------
/**
- * 构建URL:Server端向Client下放ticket的地址
- * @param loginId 账号id
- * @param client 客户端标识
- * @param redirect Client端提供的重定向地址
- * @return see note
+ * 向指定 Client 推送消息
+ * @param clientModel /
+ * @param message /
+ * @return /
*/
- public String buildRedirectUrl(Object loginId, String client, String redirect) {
-
- // 校验 重定向地址 是否合法
- checkRedirectUrl(client, redirect);
-
- // 删掉 旧Ticket
- deleteTicket(getTicketValue(loginId));
-
- // 创建 新Ticket
- String ticket = createTicket(loginId, client);
-
- // 构建 授权重定向地址 (Server端 根据此地址向 Client端 下放Ticket)
- return SaFoxUtil.joinParam(encodeBackParam(redirect), paramName.ticket, ticket);
+ public String pushMessage(SaSsoClientModel clientModel, SaSsoMessage message) {
+ message.checkType();
+ String noticeUrl = clientModel.splicingNoticeUrl();
+ String paramsStr = getSignTemplate(clientModel.getClient()).addSignParamsAndJoin(message);
+ String finalUrl = SaFoxUtil.joinParam(noticeUrl, paramsStr);
+ return request(finalUrl);
}
/**
- * 对url中的back参数进行URL编码, 解决超链接重定向后参数丢失的bug
- * @param url url
- * @return 编码过后的url
+ * 向指定 client 推送消息,并将返回值转为 SaResult
+ *
+ * @param clientModel /
+ * @param message /
+ * @return /
*/
- public String encodeBackParam(String url) {
+ public SaResult pushMessageAsSaResult(SaSsoClientModel clientModel, SaSsoMessage message) {
+ String res = pushMessage(clientModel, message);
+ Map map = SaManager.getSaJsonTemplate().jsonToMap(res);
+ return new SaResult(map);
+ }
- // 获取back参数所在位置
- int index = url.indexOf("?" + paramName.back + "=");
- if(index == -1) {
- index = url.indexOf("&" + paramName.back + "=");
- if(index == -1) {
- return url;
+ /**
+ * 向指定 Client 推送消息
+ * @param client /
+ * @param message /
+ * @return /
+ */
+ public String pushMessage(String client, SaSsoMessage message) {
+ return pushMessage(getClientNotNull(client), message);
+ }
+
+ /**
+ * 向指定 client 推送消息,并将返回值转为 SaResult
+ *
+ * @param client /
+ * @param message /
+ * @return /
+ */
+ public SaResult pushMessageAsSaResult(String client, SaSsoMessage message) {
+ String res = pushMessage(client, message);
+ Map map = SaManager.getSaJsonTemplate().jsonToMap(res);
+ return new SaResult(map);
+ }
+
+ /**
+ * 向所有 Client 推送消息
+ *
+ * @param message /
+ */
+ public void pushToAllClient(SaSsoMessage message) {
+ List mode3Clients = getNeedPushClients();
+ for (SaSsoClientModel client : mode3Clients) {
+ pushMessage(client, message);
+ }
+ }
+
+ /**
+ * 向所有 Client 推送消息:单点注销回调
+ *
+ * @param loginId /
+ */
+ public void pushToAllClientByLogoutCall(Object loginId) {
+ List npClients = getNeedPushClients();
+ for (SaSsoClientModel client : npClients) {
+ if(client.getIsSlo()) {
+ SaSsoMessage message = new SaSsoMessage();
+ message.setType(SaSsoConsts.MESSAGE_LOGOUT_CALL);
+ message.set(paramName.loginId, loginId);
+ pushMessage(client, message);
}
}
-
- // 开始编码
- int length = paramName.back.length() + 2;
- String back = url.substring(index + length);
- back = SaFoxUtil.encodeUrl(back);
-
- // 放回url中
- url = url.substring(0, index + length) + back;
- return url;
}
- // ---------------------- 重构 ----------------------
-
+ // ------------------- Bean 获取 -------------------
/**
- * 校验 Ticket 码,获取账号id,如果此ticket是有效的,则立即删除
- * @param ticket Ticket码
- * @param client client 标识
+ * 获取底层使用的SsoServer配置对象
+ * @return /
*/
- public void checkTicketVerifySign(SaRequest req, String ticket, String client) {
- SaSignTemplate signTemplate = getSignTemplate(client);
- signTemplate.checkRequest(req, paramName.client, paramName.ticket, paramName.ssoLogoutCall);
+ public SaSsoServerConfig getServerConfig() {
+ return SaSsoManager.getServerConfig();
}
-
/**
* 获取底层使用的 API 签名对象
* @param client 指定客户端标识,填 null 代表获取默认的
@@ -609,8 +703,6 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
}
-
-
// ------------------- 返回相应key -------------------
/**
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoTemplate.java
index 39465185..09a8520f 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoTemplate.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoTemplate.java
@@ -17,10 +17,15 @@ package cn.dev33.satoken.sso.template;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.sign.SaSignTemplate;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.message.SaSsoMessageHolder;
import cn.dev33.satoken.sso.name.ApiName;
import cn.dev33.satoken.sso.name.ParamName;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+
+import java.util.Map;
/**
* Sa-Token SSO 模板方法类 (公共端)
@@ -78,4 +83,40 @@ public class SaSsoTemplate {
return SaManager.getSaSignTemplate();
}
+ // ----------- 消息处理
+
+ public SaSsoMessageHolder messageHolder = new SaSsoMessageHolder();
+
+ /**
+ * 发送 Http 请求
+ *
+ * @param url /
+ * @return /
+ */
+ public String request(String url) {
+ return SaManager.getSaHttpTemplate().get(url);
+ }
+
+ /**
+ * 发送 Http 请求,并将响应结果转换为 SaResult
+ *
+ * @param url 请求地址
+ * @return 返回的结果
+ */
+ public SaResult requestAsSaResult(String url) {
+ String body = request(url);
+ Map map = SaManager.getSaJsonTemplate().jsonToMap(body);
+ return new SaResult(map);
+ }
+
+ /**
+ * 处理指定消息
+ *
+ * @param message /
+ */
+ public Object handleMessage(SaSsoMessage message) {
+ return messageHolder.handleMessage(this, message);
+ }
+
+
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoUtil.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoUtil.java
index 2ed7a8ad..f0bad5b8 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoUtil.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoUtil.java
@@ -95,16 +95,6 @@ public class SaSsoUtil {
return SaSsoServerProcessor.instance.ssoServerTemplate.checkTicket(ticket, client);
}
-// /**
-// * 获取:所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
-// *
-// * @param client 应用标识
-// * @return /
-// */
-// public static String getAllowUrl(String client) {
-// return SaSsoServerProcessor.instance.ssoServerTemplate.getAllowUrl(client);
-// }
-
/**
* 校验重定向url合法性
*
@@ -117,16 +107,6 @@ public class SaSsoUtil {
// ------------------- SSO 模式三 -------------------
-
- /**
- * 构建URL:校验ticket的URL
- * @param ticket ticket码
- * @param ssoLogoutCallUrl 单点注销时的回调URL
- * @return 构建完毕的URL
- */
- public static String buildCheckTicketUrl(String ticket, String ssoLogoutCallUrl) {
- return SaSsoClientProcessor.instance.ssoClientTemplate.buildCheckTicketUrl(ticket, ssoLogoutCallUrl);
- }
/**
* 为指定账号id注册单点注销回调URL
@@ -138,15 +118,6 @@ public class SaSsoUtil {
SaSsoServerProcessor.instance.ssoServerTemplate.registerSloCallbackUrl(loginId, client, sloCallbackUrl);
}
- /**
- * 构建URL:单点注销URL
- * @param loginId 要注销的账号id
- * @return 单点注销URL
- */
- public static String buildSloUrl(Object loginId) {
- return SaSsoClientProcessor.instance.ssoClientTemplate.buildSloUrl(loginId);
- }
-
/**
* 指定账号单点注销 (以Server方发起)
* @param loginId 指定账号
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java
index 8eea64f4..1ee4b4d9 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java
@@ -55,6 +55,18 @@ public class SaSsoConsts {
/** SSO 模式3 */
public static final int SSO_MODE_3 = 3;
+// /** 消息类型:单点注销 */
+// public static final String MESSAGE_LOGOUT = "logout";
+
+ /** 消息类型:校验 ticket */
+ public static final String MESSAGE_CHECK_TICKET = "checkTicket";
+
+ /** 消息类型:单点注销 */
+ public static final String MESSAGE_SIGNOUT = "signout";
+
+ /** 消息类型:单点注销回调 */
+ public static final String MESSAGE_LOGOUT_CALL = "logoutCall";
+
}