diff --git a/sa-token-demo/sa-token-demo-sso-for-solon/sa-token-demo-sso1-client-solon/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso-for-solon/sa-token-demo-sso1-client-solon/src/main/java/com/pj/sso/SsoClientController.java
index 5acea49a..31d4d0a4 100644
--- a/sa-token-demo/sa-token-demo-sso-for-solon/sa-token-demo-sso1-client-solon/src/main/java/com/pj/sso/SsoClientController.java
+++ b/sa-token-demo/sa-token-demo-sso-for-solon/sa-token-demo-sso1-client-solon/src/main/java/com/pj/sso/SsoClientController.java
@@ -22,7 +22,7 @@ public class SsoClientController implements Render {
@Mapping("/")
public String index() {
String authUrl = SaSsoManager.getClientConfig().splicingAuthUrl();
- String solUrl = SaSsoManager.getClientConfig().splicingSloUrl();
+ String solUrl = SaSsoManager.getClientConfig().splicingSignoutUrl();
String str = "
Sa-Token SSO-Client 应用端
" +
"当前会话是否登录:" + StpUtil.isLogin() + "
" +
"登录 " +
diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java
index aefb851e..b5138e3f 100644
--- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java
+++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java
@@ -18,7 +18,7 @@ public class SsoClientController {
@RequestMapping("/")
public String index() {
String authUrl = SaSsoManager.getClientConfig().splicingAuthUrl();
- String solUrl = SaSsoManager.getClientConfig().splicingSloUrl();
+ String solUrl = SaSsoManager.getClientConfig().splicingSignoutUrl();
String str = "
Sa-Token SSO-Client 应用端
" +
"当前会话是否登录:" + StpUtil.isLogin() + "
" +
"登录 " +
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 2fc5ecbc..537644ac 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
@@ -20,7 +20,7 @@ public class SsoClientController {
// 首页
@RequestMapping("/")
public String index() {
- String solUrl = SaSsoManager.getClientConfig().splicingSloUrl();
+ String solUrl = SaSsoManager.getClientConfig().splicingSignoutUrl();
String str = "
Sa-Token SSO-Client 应用端
" +
"当前会话是否登录:" + StpUtil.isLogin() + "
" +
"登录 " +
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoManager.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoManager.java
index 564d0530..774e137b 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoManager.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoManager.java
@@ -70,18 +70,18 @@ public class SaSsoManager {
}
}
- // 在启动时检测到 sa-token.sso.is-check-sign=false 时,输出警告信息
+ // 在启动时检测到 sa-token.sso-[server/client].is-check-sign=false 时,输出警告信息
public static void printNoCheckSignWarningByStartup() {
System.err.println("-----------------------------------------------------------------------------");
System.err.println("警告信息:");
- System.err.println("当前配置项 sa-token.sso.is-check-sign=false 代表跳过 SSO 参数签名校验");
+ System.err.println("当前配置项 sa-token.sso-[server/client].is-check-sign=false 代表跳过 SSO 参数签名校验");
System.err.println("此模式仅为方便本地调试使用,生产环境下请务必配置为 true (配置项默认为true)");
System.err.println("-----------------------------------------------------------------------------");
}
- // 在运行时检测到 sa-token.sso.is-check-sign=false 时,输出警告信息
+ // 在运行时检测到 sa-token.sso-[server/client].is-check-sign=false 时,输出警告信息
public static void printNoCheckSignWarningByRuntime() {
- System.err.println("警告信息:当前配置项 sa-token.sso.is-check-sign=false 已跳过参数签名校验," +
+ System.err.println("警告信息:当前配置项 sa-token.sso-[server/client].is-check-sign=false 已跳过参数签名校验," +
"此模式仅为方便本地调试使用,生产环境下请务必配置为 true (配置项默认为true)");
}
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 6f5d08ed..bdeb5acb 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
@@ -21,7 +21,7 @@ import cn.dev33.satoken.util.SaFoxUtil;
import java.io.Serializable;
/**
- * Sa-Token SSO 单点登录模块 配置类 (Client端)
+ * Sa-Token SSO Client 端 配置类
*
* @author click33
* @since 1.30.0
@@ -36,35 +36,35 @@ public class SaSsoClientConfig implements Serializable {
public String mode = "";
/**
- * 当前 Client 标识
+ * 当前 Client 标识(非必填,不填时代表当前应用是一个匿名应用)
*/
public String client;
/**
- * 配置 Server 端主机总地址
+ * 配置 SSO Server 端主机总地址
*/
public String serverUrl;
/**
- * 单独配置 Server 端单点登录授权地址
+ * 单独配置 Server 端:单点登录授权地址
*/
public String authUrl = "/sso/auth";
/**
- * 单独配置 Server 端查询数据 getData 地址
+ * 单独配置 Server 端:单点注销地址
*/
- public String getDataUrl = "/sso/getData";
+ public String signoutUrl = "/sso/signout";
/**
- * 单独配置 Server 端单点注销地址
- */
- public String sloUrl = "/sso/signout";
-
- /**
- * 单独配置 Server 端推送消息地址
+ * 单独配置 Server 端:推送消息地址
*/
public String pushUrl = "/sso/pushS";
+ /**
+ * 单独配置 Server 端:查询数据 getData 地址
+ */
+ public String getDataUrl = "/sso/getData";
+
/**
* 配置当前 Client 端的登录地址(为空时自动获取)
*/
@@ -75,6 +75,11 @@ public class SaSsoClientConfig implements Serializable {
*/
public String currSsoLogoutCall;
+ /**
+ * 是否打开模式三(此值为 true 时将使用 http 请求校验 ticket 值)
+ */
+ public Boolean isHttp = false;
+
/**
* 是否打开单点注销功能 (为 true 时,接收单点注销回调消息推送)
*/
@@ -85,18 +90,13 @@ public class SaSsoClientConfig implements Serializable {
*/
public Boolean regLogoutCall = false;
- /**
- * 是否打开模式三(此值为 true 时将使用 http 请求校验 ticket 值)
- */
- public Boolean isHttp = false;
-
/**
* API 调用签名秘钥
*/
public String secretKey;
/**
- * 是否校验参数签名(方便本地调试用的一个配置项,生产环境请务必为true)
+ * 是否校验参数签名(为 false 时暂时关闭参数签名校验,此为方便本地调试用的一个配置项,生产环境请务必为true)
*/
public Boolean isCheckSign = true;
@@ -104,28 +104,28 @@ public class SaSsoClientConfig implements Serializable {
// 额外添加的一些函数
/**
- * @return 获取拼接url:Server 端单点登录授权地址
+ * @return 获取拼接 url:Server 端单点登录授权地址
*/
public String splicingAuthUrl() {
return SaFoxUtil.spliceTwoUrl(getServerUrl(), getAuthUrl());
}
/**
- * @return 获取拼接url:Server 端查询数据 getData 地址
+ * @return 获取拼接 url:Server 端查询数据 getData 地址
*/
public String splicingGetDataUrl() {
return SaFoxUtil.spliceTwoUrl(getServerUrl(), getGetDataUrl());
}
/**
- * @return 获取拼接url:Server 端单点注销地址
+ * @return 获取拼接 url:Server 端单点注销地址
*/
- public String splicingSloUrl() {
- return SaFoxUtil.spliceTwoUrl(getServerUrl(), getSloUrl());
+ public String splicingSignoutUrl() {
+ return SaFoxUtil.spliceTwoUrl(getServerUrl(), getSignoutUrl());
}
/**
- * @return 获取拼接url:单独配置 Server 端推送消息地址
+ * @return 获取拼接 url:单独配置 Server 端推送消息地址
*/
public String splicingPushUrl() {
return SaFoxUtil.spliceTwoUrl(getServerUrl(), getPushUrl());
@@ -153,14 +153,14 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return 是否打开单点注销功能
+ * @return 是否打开单点注销功能 (为 true 时,接收单点注销回调消息推送)
*/
public Boolean getIsSlo() {
return isSlo;
}
/**
- * @param isSlo 是否打开单点注销功能
+ * @param isSlo 是否打开单点注销功能 (为 true 时,接收单点注销回调消息推送)
* @return 对象自身
*/
public SaSsoClientConfig setIsSlo(Boolean isSlo) {
@@ -169,14 +169,14 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return isHttp 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、拉取数据getData)
+ * @return isHttp 是否打开模式三(此值为 true 时将使用 http 请求校验 ticket 值)
*/
public Boolean getIsHttp() {
return isHttp;
}
/**
- * @param isHttp 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、拉取数据getData)
+ * @param isHttp 是否打开模式三(此值为 true 时将使用 http 请求校验 ticket 值)
* @return 对象自身
*/
public SaSsoClientConfig setIsHttp(Boolean isHttp) {
@@ -185,14 +185,18 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return 当前 Client 名称标识,用于和 ticket 码的互相锁定
+ * 当前 Client 标识(非必填,不填时代表当前应用是一个匿名应用)
+ *
+ * @return /
*/
public String getClient() {
return client;
}
/**
- * @param client 当前 Client 名称标识,用于和 ticket 码的互相锁定
+ * 当前 Client 标识(非必填,不填时代表当前应用是一个匿名应用)
+ *
+ * @param client /
*/
public SaSsoClientConfig setClient(String client) {
this.client = client;
@@ -200,14 +204,14 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return 配置的 Server 端单点登录授权地址
+ * @return 单独配置 Server 端:单点登录授权地址
*/
public String getAuthUrl() {
return authUrl;
}
/**
- * @param authUrl 配置 Server 端单点登录授权地址
+ * @param authUrl 单独配置 Server 端:单点登录授权地址
* @return 对象自身
*/
public SaSsoClientConfig setAuthUrl(String authUrl) {
@@ -216,14 +220,14 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return Server 端查询数据 getData 地址
+ * @return 单独配置 Server 端:查询数据 getData 地址
*/
public String getGetDataUrl() {
return getDataUrl;
}
/**
- * @param getDataUrl 配置 Server 端查询数据 getData 地址
+ * @param getDataUrl 单独配置 Server 端:查询数据 getData 地址
* @return 对象自身
*/
public SaSsoClientConfig setGetDataUrl(String getDataUrl) {
@@ -232,23 +236,23 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return 配置 Server 端单点注销地址
+ * @return 单独配置 Server 端:单点注销地址
*/
- public String getSloUrl() {
- return sloUrl;
+ public String getSignoutUrl() {
+ return signoutUrl;
}
/**
- * @param sloUrl 配置 Server 端单点注销地址
+ * @param signoutUrl 单独配置 Server 端:单点注销地址
* @return 对象自身
*/
- public SaSsoClientConfig setSloUrl(String sloUrl) {
- this.sloUrl = sloUrl;
+ public SaSsoClientConfig setSignoutUrl(String signoutUrl) {
+ this.signoutUrl = signoutUrl;
return this;
}
/**
- * 获取 单独配置 Server 端推送消息地址
+ * 获取 单独配置 Server 端:推送消息地址
*
* @return /
*/
@@ -257,7 +261,7 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * 设置 单独配置 Server 端推送消息地址
+ * 设置 单独配置 Server 端:推送消息地址
*
* @param pushUrl /
* @return 对象自身
@@ -300,14 +304,18 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * @return 配置的 Server 端主机总地址,拼接在 authUrl、checkTicketUrl、getDataUrl、sloUrl 属性前面,用以简化各种 url 配置
+ * 配置 SSO Server 端主机总地址
+ *
+ * @return /
*/
public String getServerUrl() {
return serverUrl;
}
/**
- * @param serverUrl 配置 Server 端主机总地址,拼接在 authUrl、checkTicketUrl、getDataUrl、sloUrl 属性前面,用以简化各种 url 配置
+ * 配置 SSO Server 端主机总地址
+ *
+ * @param serverUrl /
* @return 对象自身
*/
public SaSsoClientConfig setServerUrl(String serverUrl) {
@@ -336,7 +344,7 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * 获取 是否校验参数签名(方便本地调试用的一个配置项,生产环境请务必为true)
+ * 获取 是否校验参数签名(为 false 时暂时关闭参数签名校验,此为方便本地调试用的一个配置项,生产环境请务必为true)
*
* @return isCheckSign 是否校验参数签名(方便本地调试用的一个配置项,生产环境请务必为true)
*/
@@ -345,7 +353,7 @@ public class SaSsoClientConfig implements Serializable {
}
/**
- * 设置 是否校验参数签名(方便本地调试用的一个配置项,生产环境请务必为true)
+ * 设置 是否校验参数签名(为 false 时暂时关闭参数签名校验,此为方便本地调试用的一个配置项,生产环境请务必为true)
*
* @param isCheckSign 是否校验参数签名(方便本地调试用的一个配置项,生产环境请务必为true)
*/
@@ -381,8 +389,9 @@ public class SaSsoClientConfig implements Serializable {
+ ", client=" + client
+ ", serverUrl=" + serverUrl
+ ", authUrl=" + authUrl
+ + ", signoutUrl=" + signoutUrl
+ + ", pushUrl=" + pushUrl
+ ", getDataUrl=" + getDataUrl
- + ", sloUrl=" + sloUrl
+ ", currSsoLogin=" + currSsoLogin
+ ", currSsoLogoutCall=" + currSsoLogoutCall
+ ", isHttp=" + isHttp
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 b1e6a909..fefe9896 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
@@ -16,6 +16,8 @@
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.template.SaSsoServerTemplate;
import cn.dev33.satoken.util.SaFoxUtil;
@@ -23,29 +25,29 @@ import java.io.Serializable;
import java.util.List;
/**
- * Sa-Token SSO 客户端信息配置
+ * Sa-Token SSO 客户端信息配置 (在 Server 端配置允许接入的 Client 信息)
*
* @author click33
- * @since 1.42.0
+ * @since 1.43.0
*/
public class SaSsoClientModel implements Serializable {
private static final long serialVersionUID = -6541180061782004705L;
/**
- * 当前 Client 名称标识,用于和 ticket 码的互相锁定
+ * Client 名称标识
*/
public String client;
/**
- * 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
+ * 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的 URL 将禁止下放 ticket )
*/
public String allowUrl = "*";
/**
- * 是否打开模式三(此值为 true 时使用 http 调用方式进行消息通知)
+ * 是否接收推送消息
*/
- public Boolean isHttp = false;
+ public Boolean isPush = false;
/**
* 是否打开单点注销功能
@@ -63,7 +65,7 @@ public class SaSsoClientModel implements Serializable {
public String serverUrl;
/**
- * 此 Client 端推送消息的地址
+ * 此 Client 端推送消息的地址 (如不配置,默认根据 serverUrl + '/sso/pushC' 进行拼接)
*/
public String pushUrl = "/sso/pushC";
@@ -85,8 +87,12 @@ public class SaSsoClientModel implements Serializable {
*
* @return /
*/
- public String splicingNoticeUrl() {
- return SaFoxUtil.spliceTwoUrl(getServerUrl(), getPushUrl());
+ public String splicingPushUrl() {
+ String _pushUrl = SaFoxUtil.spliceTwoUrl(getServerUrl(), getPushUrl());
+ if ( ! SaFoxUtil.isUrl(_pushUrl)) {
+ throw new SaSsoException("应用 [" + getClient() + "] 推送地址无效:" + _pushUrl).setCode(SaSsoErrorCode.CODE_30023);
+ }
+ return _pushUrl;
}
/**
@@ -94,22 +100,22 @@ public class SaSsoClientModel implements Serializable {
*
* @return /
*/
- public boolean isValidNoticeUrl() {
- return SaFoxUtil.isUrl(splicingNoticeUrl());
+ public boolean isValidPushUrl() {
+ return SaFoxUtil.isUrl(splicingPushUrl());
}
// get set
/**
- * @return 当前 Client 名称标识
+ * @return Client 名称标识
*/
public String getClient() {
return client;
}
/**
- * @param client 当前 Client 名称标识
+ * @param client Client 名称标识
*/
public SaSsoClientModel setClient(String client) {
this.client = client;
@@ -117,14 +123,14 @@ public class SaSsoClientModel implements Serializable {
}
/**
- * @return 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
+ * @return 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的 URL 将禁止下放 ticket )
*/
public String getAllowUrl() {
return allowUrl;
}
/**
- * @param allowUrl 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的URL将禁止下放ticket)
+ * @param allowUrl 所有允许的授权回调地址,多个用逗号隔开 (不在此列表中的 URL 将禁止下放 ticket )
* @return 对象自身
*/
public SaSsoClientModel setAllowUrl(String allowUrl) {
@@ -140,16 +146,16 @@ public class SaSsoClientModel implements Serializable {
/**
* @return isHttp 是否打开模式三
*/
- public Boolean getIsHttp() {
- return isHttp;
+ public Boolean getIsPush() {
+ return isPush;
}
/**
- * @param isHttp 是否打开模式三
+ * @param isPush 是否打开模式三
* @return 对象自身
*/
- public SaSsoClientModel setIsHttp(Boolean isHttp) {
- this.isHttp = isHttp;
+ public SaSsoClientModel setIsPush(Boolean isPush) {
+ this.isPush = isPush;
return this;
}
@@ -210,16 +216,16 @@ public class SaSsoClientModel implements Serializable {
}
/**
- * 获取 此 Client 端推送消息的地址
+ * 获取 此 Client 端推送消息的地址 (如不配置,默认根据 serverUrl + '/sso/pushC' 进行拼接)
*
- * @return noticeUrl 此 Client 端推送消息的地址
+ * @return /
*/
public String getPushUrl() {
return this.pushUrl;
}
/**
- * 设置 此 Client 端推送消息的地址
+ * 设置 此 Client 端推送消息的地址 (如不配置,默认根据 serverUrl + '/sso/pushC' 进行拼接)
*
* @param pushUrl 此 Client 端推送消息的地址
* @return 对象自身
@@ -235,7 +241,7 @@ public class SaSsoClientModel implements Serializable {
+ "client=" + client
+ ", allowUrl=" + allowUrl
+ ", isSlo=" + isSlo
- + ", isHttp=" + isHttp
+ + ", isPush=" + isPush
+ ", 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 a84793fb..1ad410a9 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
@@ -25,7 +25,7 @@ import java.util.List;
import java.util.Map;
/**
- * Sa-Token SSO 单点登录模块 配置类 (Server端)
+ * Sa-Token SSO Server 端 配置类
*
* @author click33
* @since 1.38.0
@@ -43,7 +43,7 @@ public class SaSsoServerConfig implements Serializable {
public String mode = "";
/**
- * Ticket有效期 (单位: 秒)
+ * ticket 有效期 (单位: 秒)
*/
public long ticketTimeout = 60 * 5;
@@ -53,7 +53,7 @@ public class SaSsoServerConfig implements Serializable {
public String homeRoute;
/**
- * 是否打开单点注销功能
+ * 是否打开单点注销功能 (为 true 时接收 client 端推送的单点注销消息)
*/
public Boolean isSlo = true;
@@ -98,7 +98,7 @@ public class SaSsoServerConfig implements Serializable {
// 额外方法
/**
- * 以数组形式写入允许的授权回调地址
+ * 以数组形式写入允许的授权回调地址 (不在此列表中的URL将禁止下放ticket) (匿名 client 使用)
* @param url 所有集合
* @return 对象自身
*/
@@ -139,14 +139,14 @@ public class SaSsoServerConfig implements Serializable {
}
/**
- * @return Ticket有效期 (单位: 秒)
+ * @return ticket 有效期 (单位: 秒)
*/
public long getTicketTimeout() {
return ticketTimeout;
}
/**
- * @param ticketTimeout Ticket有效期 (单位: 秒)
+ * @param ticketTimeout ticket 有效期 (单位: 秒)
* @return 对象自身
*/
public SaSsoServerConfig setTicketTimeout(long ticketTimeout) {
@@ -192,14 +192,14 @@ public class SaSsoServerConfig implements Serializable {
}
/**
- * @return 是否打开单点注销功能
+ * @return 是否打开单点注销功能 (为 true 时接收 client 端推送的单点注销消息)
*/
public Boolean getIsSlo() {
return isSlo;
}
/**
- * @param isSlo 是否打开单点注销功能
+ * @param isSlo 是否打开单点注销功能 (为 true 时接收 client 端推送的单点注销消息)
* @return 对象自身
*/
public SaSsoServerConfig setIsSlo(Boolean isSlo) {
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 e1bb6fe5..88666a86 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
@@ -77,4 +77,7 @@ public interface SaSsoErrorCode {
/** 无效的消息推送地址 */
int CODE_30023 = 30023;
+ /** SSO 消息里缺少指定的参数 */
+ int CODE_30024 = 30024;
+
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/CheckTicketAppendDataFunction.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/CheckTicketAppendDataFunction.java
index b99bb802..5405a11a 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/CheckTicketAppendDataFunction.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/CheckTicketAppendDataFunction.java
@@ -20,7 +20,7 @@ import cn.dev33.satoken.util.SaResult;
import java.util.function.BiFunction;
/**
- * 函数式接口:SSO-Server端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
+ * 函数式接口:sso-server 端:在校验 ticket 后,给 sso-client 端追加返回信息的函数
*
*
参数:loginId, SaResult 响应参数对象
* 返回:SaResult 响应参数对象
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/DoLoginHandleFunction.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/DoLoginHandleFunction.java
index b5dd7566..7e854fa6 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/DoLoginHandleFunction.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/DoLoginHandleFunction.java
@@ -18,7 +18,7 @@ package cn.dev33.satoken.sso.function;
import java.util.function.BiFunction;
/**
- * 函数式接口:SSO-Server端:登录处理函数
+ * 函数式接口:sso-server 端:登录处理函数
*
* 参数:账号、密码
* 返回:登录结果
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/NotLoginViewFunction.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/NotLoginViewFunction.java
index 644a0a94..3f8a52cb 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/NotLoginViewFunction.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/NotLoginViewFunction.java
@@ -18,7 +18,7 @@ package cn.dev33.satoken.sso.function;
import java.util.function.Supplier;
/**
- * 函数式接口:SSO-Server端:未登录时返回的View
+ * 函数式接口:sso-server 端:未登录时返回的 View
*
* 参数:无
* 返回:未登录时的 View 视图
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/SendHttpFunction.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/SendHttpFunction.java
index 874e8a7e..8e124bc7 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/SendHttpFunction.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/SendHttpFunction.java
@@ -18,7 +18,7 @@ package cn.dev33.satoken.sso.function;
import java.util.function.Function;
/**
- * 函数式接口:发送Http请求的处理函数
+ * 函数式接口:发送 Http 请求的处理函数
*
* 参数:要请求的url
* 返回:请求结果
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/TicketResultHandleFunction.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/TicketResultHandleFunction.java
index 739d4658..f175d449 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/TicketResultHandleFunction.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/function/TicketResultHandleFunction.java
@@ -18,7 +18,7 @@ package cn.dev33.satoken.sso.function;
import cn.dev33.satoken.sso.model.SaCheckTicketResult;
/**
- * 函数式接口:SSO-Client端:自定义校验 ticket 返回值的处理逻辑 (每次从认证中心获取校验 ticket 的结果后调用)
+ * 函数式接口:sso-client 端:自定义校验 ticket 返回值的处理逻辑 (每次从认证中心获取校验 ticket 的结果后调用)
*
* 参数:loginId, back
* 返回:返回给前端的值
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
index 41098682..2fde8254 100644
--- 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
@@ -26,7 +26,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
/**
- * Sa-Token SSO 消息 Model
+ * SSO 消息 Model
*
* @author click33
* @since 1.43.0
@@ -108,4 +108,19 @@ public class SaSsoMessage extends LinkedHashMap implements SaSet
return this;
}
+ // -----------
+
+ /**
+ * 获取一个值 (此值必须存在,否则抛出异常 )
+ * @param key 键
+ * @return 参数值
+ */
+ public Object getValueNotNull(String key) {
+ Object value = get(key);
+ if(SaFoxUtil.isEmpty(value)) {
+ throw new SaSsoException("缺少参数:" + key).setCode(SaSsoErrorCode.CODE_30024);
+ }
+ return value;
+ }
+
}
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
index 0b68cde7..56ab9eca 100644
--- 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
@@ -25,7 +25,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
/**
- * Sa-Token SSO 消息处理器持有者
+ * SSO 消息处理器 - 持有器
*
* @author click33
* @since 1.43.0
@@ -33,7 +33,7 @@ import java.util.Map;
public class SaSsoMessageHolder {
/**
- * 所有消息处理器的集合
+ * 所有已注册的消息处理器
*/
public final Map messageHandleMap = new LinkedHashMap<>();
@@ -61,6 +61,7 @@ public class SaSsoMessageHolder {
* 添加指定类型的消息处理器
*
* @param handle /
+ * @return 对象自身
*/
public SaSsoMessageHolder addHandle(SaSsoMessageHandle handle) {
messageHandleMap.put(handle.getHandlerType(), handle);
@@ -81,7 +82,7 @@ public class SaSsoMessageHolder {
*
* @param ssoTemplate /
* @param message /
- * @return /
+ * @return 处理结果
*/
public Object handleMessage(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
SaSsoMessageHandle handle = messageHandleMap.get(message.getType());
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
index 32944139..651ad7cf 100644
--- 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
@@ -20,7 +20,7 @@ import cn.dev33.satoken.sso.message.SaSsoMessage;
import cn.dev33.satoken.sso.template.SaSsoTemplate;
/**
- * Sa-Token SSO 消息 处理器
+ * SSO 消息处理器 - 父接口
*
* @author click33
* @since 1.43.0
@@ -35,7 +35,7 @@ public interface SaSsoMessageHandle {
String getHandlerType();
/**
- * 执行方法
+ * 具体要执行的处理方法
*
* @param ssoTemplate /
* @param 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
index 3e1f4d91..5a8ecfb3 100644
--- 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
@@ -29,7 +29,7 @@ import cn.dev33.satoken.stp.parameter.SaLogoutParameter;
import cn.dev33.satoken.util.SaResult;
/**
- * Sa-Token SSO 消息 处理器 - sso-client 端:处理 单点注销回调 的请求
+ * SSO 消息处理器 - sso-client 端:处理 单点注销回调 的请求
*
* @author click33
* @since 1.43.0
@@ -53,27 +53,28 @@ public class SaSsoMessageLogoutCallHandle implements SaSsoMessageHandle {
* @return /
*/
public Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+
+ // 1、获取对象
SaSsoClientTemplate ssoClientTemplate = (SaSsoClientTemplate) ssoTemplate;
+ StpLogic stpLogic = ssoClientTemplate.getStpLogic();
+ ParamName paramName = ssoClientTemplate.paramName;
+
+ // 2、判断当前应用是否开启单点注销功能
if( ! ssoClientTemplate.getClientConfig().getIsSlo()) {
return SaResult.error("当前 sso-client 端未开启单点注销功能");
}
- // 获取对象
- SaRequest req = SaHolder.getRequest();
- StpLogic stpLogic = ssoClientTemplate.getStpLogic();
- ParamName paramName = ssoClientTemplate.paramName;
-
- // 获取参数
- Object loginId = req.getParamNotNull(paramName.loginId);
+ // 3、获取参数
+ Object loginId = message.getValueNotNull(paramName.loginId);
loginId = ssoClientTemplate.strategy.convertCenterIdToLoginId.run(loginId);
String deviceId = message.getString(paramName.deviceId);
- // 注销当前应用端会话
+ // 4、注销当前应用端会话
stpLogic.logout(loginId, new SaLogoutParameter()
.setDeviceId(deviceId)
);
- // 响应
+ // 5、响应
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
index cc523dcc..6e2a64db 100644
--- 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
@@ -16,9 +16,6 @@
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.config.SaSsoServerConfig;
import cn.dev33.satoken.sso.message.SaSsoMessage;
import cn.dev33.satoken.sso.message.handle.SaSsoMessageHandle;
import cn.dev33.satoken.sso.model.TicketModel;
@@ -30,7 +27,7 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.util.SaResult;
/**
- * Sa-Token SSO 消息 处理器 - sso-server 端:处理校验 ticket 的请求
+ * SSO 消息处理器 - sso-server 端:处理校验 ticket 的请求
*
* @author click33
* @since 1.43.0
@@ -54,38 +51,23 @@ public class SaSsoMessageCheckTicketHandle implements SaSsoMessageHandle {
* @return /
*/
public Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+
+ // 1、获取对象
SaSsoServerTemplate ssoServerTemplate = (SaSsoServerTemplate) ssoTemplate;
ParamName paramName = ssoServerTemplate.paramName;
-
- // 1、获取参数
- SaRequest req = SaHolder.getRequest();
- SaSsoServerConfig ssoServerConfig = ssoServerTemplate.getServerConfig();
StpLogic stpLogic = ssoServerTemplate.getStpLogic();
- String client = req.getParam(paramName.client);
- String ticket = req.getParamNotNull(paramName.ticket);
- String sloCallback = req.getParam(paramName.ssoLogoutCall);
+ String client = message.getString(paramName.client);
+ String ticket = message.getValueNotNull(paramName.ticket).toString();
+ String sloCallback = message.getString(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
+ // 2、校验ticket,获取 loginId
TicketModel ticketModel = ssoServerTemplate.checkTicketParamAndDelete(ticket, client);
Object loginId = ticketModel.getLoginId();
- // 5、注册此客户端的单点注销回调URL
+ // 3、注册此客户端的登录信息
ssoServerTemplate.registerSloCallbackUrl(loginId, client, sloCallback);
- // 6、给 client 端响应结果
+ // 4、给 client 端响应结果
SaResult result = SaResult.ok();
result.setData(loginId); // 兼容历史版本
result.set(paramName.loginId, loginId);
@@ -93,7 +75,6 @@ public class SaSsoMessageCheckTicketHandle implements SaSsoMessageHandle {
result.set(paramName.deviceId, stpLogic.getLoginDeviceIdByToken(ticketModel.getTokenValue()));
result.set(paramName.remainTokenTimeout, stpLogic.getTokenTimeout(ticketModel.getTokenValue()));
result.set(paramName.remainSessionTimeout, stpLogic.getSessionTimeoutByLoginId(loginId));
-
result = ssoServerTemplate.strategy.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
index 728b007f..b470d7c4 100644
--- 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
@@ -16,8 +16,6 @@
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;
@@ -28,7 +26,7 @@ import cn.dev33.satoken.stp.parameter.SaLogoutParameter;
import cn.dev33.satoken.util.SaResult;
/**
- * Sa-Token SSO 消息 处理器 - sso-server 端:处理 单点注销 的请求
+ * SSO 消息处理器 - sso-server 端:处理 单点注销 的请求
*
* @author click33
* @since 1.43.0
@@ -52,24 +50,25 @@ public class SaSsoMessageSignoutHandle implements SaSsoMessageHandle {
* @return /
*/
public Object handle(SaSsoTemplate ssoTemplate, SaSsoMessage message) {
+
+ // 1、获取对象
SaSsoServerTemplate ssoServerTemplate = (SaSsoServerTemplate) ssoTemplate;
ParamName paramName = ssoServerTemplate.paramName;
+ // 2、判断当前是否开启了全局单点注销功能
if( ! ssoServerTemplate.getServerConfig().getIsSlo()) {
return SaResult.error("当前 sso-server 端未开启单点注销功能");
}
- // 获取参数
- SaRequest req = SaHolder.getRequest();
- String loginId = req.getParam(paramName.loginId);
- String deviceId = req.getParam(paramName.deviceId);
+ // 3、获取参数
+ Object loginId = message.get(paramName.loginId);
+ String deviceId = message.getString(paramName.deviceId);
- // step.2 单点注销
- SaLogoutParameter logoutParameter = ssoServerTemplate.getStpLogic().createSaLogoutParameter()
- .setDeviceId(deviceId);
+ // 4、单点注销
+ SaLogoutParameter logoutParameter = ssoServerTemplate.getStpLogic().createSaLogoutParameter().setDeviceId(deviceId);
ssoServerTemplate.ssoLogout(loginId, logoutParameter);
- // 响应
+ // 5、响应
return SaResult.ok();
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaCheckTicketResult.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaCheckTicketResult.java
index a6880952..5fe847e3 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaCheckTicketResult.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaCheckTicketResult.java
@@ -47,12 +47,9 @@ public class SaCheckTicketResult implements Serializable {
/** 此账号在认证中心的 loginId */
public Object centerId;
- /** 从 sso-server 返回的所有参数 */
+ /** 从 sso-server 返回的原生所有参数 */
public SaResult result;
- public SaCheckTicketResult() {
- }
-
@Override
public String toString() {
return "SaCheckTicketResult{" +
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaSsoClientInfo.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaSsoClientInfo.java
index 05748f29..76397fe0 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaSsoClientInfo.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/SaSsoClientInfo.java
@@ -21,7 +21,7 @@ import cn.dev33.satoken.sso.util.SaSsoConsts;
import java.io.Serializable;
/**
- * Sa-Token SSO 应用信息
+ * Sa-Token SSO 应用信息(注册在 SaSession 上的已登录应用信息列表)
*
* @author click33
* @since 1.38.0
@@ -45,13 +45,8 @@ public class SaSsoClientInfo implements Serializable {
*/
public String client;
-// /**
-// * 此次登录 token 值
-// */
-// public String tokenValue;
-
/**
- * 单点注销回调url
+ * 单点注销回调 url
*/
public String sloCallbackUrl;
@@ -80,6 +75,8 @@ public class SaSsoClientInfo implements Serializable {
}
+ // get set
+
/**
* 获取 此 client 登录模式(1=模式一,2=模式二,3=模式三)
*
@@ -120,26 +117,6 @@ public class SaSsoClientInfo implements Serializable {
return this;
}
-// /**
-// * 获取 此次登录 token 值
-// *
-// * @return tokenValue 此次登录 token 值
-// */
-// public String getTokenValue() {
-// return this.tokenValue;
-// }
-//
-// /**
-// * 设置 此次登录 token 值
-// *
-// * @param tokenValue 此次登录 token 值
-// * @return /
-// */
-// public SaSsoClientModel setTokenValue(String tokenValue) {
-// this.tokenValue = tokenValue;
-// return this;
-// }
-
/**
* 获取 单点注销回调url
*
@@ -205,7 +182,6 @@ public class SaSsoClientInfo implements Serializable {
return "SaSsoClientModel{" +
"mode=" + mode +
", client='" + client + '\'' +
-// ", tokenValue='" + tokenValue + '\'' +
", sloCallbackUrl='" + sloCallbackUrl + '\'' +
", regTime=" + regTime +
", index=" + index +
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/TicketModel.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/TicketModel.java
index c766e6f4..4d4218e6 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/TicketModel.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/model/TicketModel.java
@@ -37,11 +37,6 @@ public class TicketModel implements Serializable {
*/
public String client;
-// /**
-// * 设备 id
-// */
-// public String deviceId;
-
/**
* 对应 loginId
*/
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 5906c742..06d1b8ed 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,7 +32,7 @@ public class ApiName {
/** SSO-Server端:校验ticket 获取账号id */
public String ssoCheckTicket = "/sso/checkTicket";
- /** SSO-Server端:接受推送消息 */
+ /** SSO-Server端:接收推送消息 */
public String ssoPushS = "/sso/pushS";
/** SSO-Server端:获取userinfo */
@@ -53,11 +53,11 @@ public class ApiName {
/** SSO-Client端:单点注销的回调 */
public String ssoLogoutCall = "/sso/logoutCall";
- /** SSO-Client端:接受推送消息 */
+ /** SSO-Client端:接收推送消息 */
public String ssoPushC = "/sso/pushC";
/**
- * 批量修改path,新增固定前缀
+ * 批量修改 path,新增固定前缀
* @param prefix 示例值:/sso-user、/sso-admin
* @return 对象自身
*/
@@ -77,7 +77,7 @@ public class ApiName {
}
/**
- * 批量修改path,替换掉 /sso 固定前缀
+ * 批量修改 path,替换掉 /sso 固定前缀
* @param prefix 示例值:/sso-user、/sso-admin
* @return 对象自身
*/
@@ -106,6 +106,7 @@ public class ApiName {
", ssoPushS='" + ssoPushS + '\'' +
", ssoUserinfo='" + ssoUserinfo + '\'' +
", ssoSignout='" + ssoSignout + '\'' +
+ ", ssoIsLogin='" + ssoIsLogin + '\'' +
", ssoLogin='" + ssoLogin + '\'' +
", ssoLogout='" + ssoLogout + '\'' +
", ssoLogoutCall='" + ssoLogoutCall + '\'' +
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java
index 2687677b..5c338872 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java
@@ -23,40 +23,40 @@ package cn.dev33.satoken.sso.name;
*/
public class ParamName {
- /** redirect参数名称 */
+ /** redirect 参数名称 */
public String redirect = "redirect";
- /** ticket参数名称 */
+ /** ticket 参数名称 */
public String ticket = "ticket";
- /** back参数名称 */
+ /** back 参数名称 */
public String back = "back";
- /** mode参数名称 */
+ /** mode 参数名称 */
public String mode = "mode";
- /** loginId参数名称 */
+ /** 账号 id */
public String loginId = "loginId";
- /** client参数名称 */
+ /** client 应用标识 */
public String client = "client";
- /** tokenName 参数 */
+ /** token 名称 */
public String tokenName = "tokenName";
- /** tokenValue 参数 */
+ /** token 值 */
public String tokenValue = "tokenValue";
- /** deviceId 参数名称 */
+ /** 设备 id */
public String deviceId = "deviceId";
- /** secretkey参数名称 */
+ /** 接口参数签名秘钥 */
public String secretkey = "secretkey";
- /** Client端单点注销时-回调URL 参数名称 */
+ /** Client 端单点注销时 - 回调 URL 参数名称 */
public String ssoLogoutCall = "ssoLogoutCall";
- /** 是否为超过 maxRegClient 的自动注销 */
+ /** 是否为超过 maxRegClient 触发的自动注销 */
public String autoLogout = "autoLogout";
public String name = "name";
@@ -72,13 +72,8 @@ public class ParamName {
/** token 剩余有效期 参数名称 */
public String remainTokenTimeout = "remainTokenTimeout";
- /** singleDeviceIdLogout 参数 */
+ /** 是否单设备 id 注销 */
public String singleDeviceIdLogout = "singleDeviceIdLogout";
- public String isLogin = "isLogin";
- public String authUrl = "authUrl";
- public String redirectUrl = "redirectUrl";
- public String currSsoLoginUrl = "currSsoLoginUrl";
-
}
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 8e818449..8134c12d 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
@@ -70,22 +70,22 @@ public class SaSsoClientProcessor {
// ------------------ 路由分发 ------------------
- // ---------- SSO-Client端:登录地址
+ // sso-client:登录地址
if(req.isPath(apiName.ssoLogin)) {
return ssoLogin();
}
- // ---------- SSO-Client端:单点注销
+ // sso-client:单点注销
if(req.isPath(apiName.ssoLogout)) {
return ssoLogout();
}
- // ---------- SSO-Client端:接收消息推送
+ // sso-client:接收消息推送
if(req.isPath(apiName.ssoPushC)) {
return ssoPushC();
}
- // ---------- SSO-Client端:单点注销的回调 [模式三]
+ // sso-client:单点注销的回调
if(req.isPath(apiName.ssoLogoutCall) && cfg.getRegLogoutCall()) {
return ssoLogoutCall();
}
@@ -101,55 +101,18 @@ public class SaSsoClientProcessor {
public Object ssoLogin() {
// 获取对象
SaRequest req = SaHolder.getRequest();
- SaResponse res = SaHolder.getResponse();
- SaSsoClientConfig cfg = ssoClientTemplate.getClientConfig();
- StpLogic stpLogic = ssoClientTemplate.getStpLogic();
- ApiName apiName = ssoClientTemplate.apiName;
ParamName paramName = ssoClientTemplate.paramName;
-
- // 获取参数
- String back = req.getParam(paramName.back, "/");
String ticket = req.getParam(paramName.ticket);
/*
* 此时有两种情况:
- * 情况1:ticket无值,说明此请求是Client端访问,需要重定向至SSO认证中心
- * 情况2:ticket有值,说明此请求从SSO认证中心重定向而来,需要根据ticket进行登录
+ * 情况1:ticket 无值,说明此请求是 sso-client 端访问,需要重定向至 sso-server 认证中心
+ * 情况2:ticket 有值,说明此请求从 sso-server 认证中心重定向而来,需要根据 ticket 进行登录
*/
if(ticket == null) {
- // 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回
- if(stpLogic.isLogin()) {
- return res.redirect(back);
- }
-
- // 获取当前项目的 sso 登录地址
- // 全局配置了就是用全局的,否则使用当前请求的地址
- String currSsoLoginUrl;
- if(SaFoxUtil.isNotEmpty(cfg.getCurrSsoLogin())) {
- currSsoLoginUrl = cfg.getCurrSsoLogin();
- } else {
- currSsoLoginUrl = SaHolder.getRequest().getUrl();
- }
- // 构建url
- String serverAuthUrl = ssoClientTemplate.buildServerAuthUrl(currSsoLoginUrl, back);
- return res.redirect(serverAuthUrl);
+ return _goServerAuth();
} else {
- // 1、校验ticket,获取 loginId
- SaCheckTicketResult ctr = checkTicket(ticket, apiName.ssoLogin);
- ctr.centerId = ctr.loginId;
- ctr.loginId = ssoClientTemplate.strategy.convertCenterIdToLoginId.run(ctr.centerId);
-
- // 2、如果开发者自定义了ticket结果值处理函数,则使用自定义的函数
- if(ssoClientTemplate.strategy.ticketResultHandle != null) {
- return ssoClientTemplate.strategy.ticketResultHandle.run(ctr, back);
- }
-
- // 3、登录并重定向至back地址
- stpLogic.login(ctr.loginId, new SaLoginParameter()
- .setTimeout(ctr.remainTokenTimeout)
- .setDeviceId(ctr.deviceId)
- );
- return res.redirect(back);
+ return _loginByTicket();
}
}
@@ -162,9 +125,10 @@ public class SaSsoClientProcessor {
SaSsoClientConfig cfg = ssoClientTemplate.getClientConfig();
// 无论登录时选择的是模式二还是模式三
- // 在注销时都应该按照模式三的方法,通过 http 请求调用 sso-server 的单点注销接口来做到全端下线
+ // 在注销时都应该按照模式三的方法,通过 http 请求调用 sso-server 的单点注销接口来做到全端下线
+ // 如果按照模式二的方法注销,则会导致按照模式三登录的应用无法参与到单点注销环路中来
if(cfg.getIsSlo()) {
- return ssoLogoutByMode3();
+ return _ssoLogoutByMode3();
}
// 默认返回
@@ -192,63 +156,6 @@ public class SaSsoClientProcessor {
return ssoClientTemplate.handleMessage(message);
}
- /**
- * SSO-Client端:单点注销 [模式二]
- * @return 处理结果
- */
- public Object ssoLogoutByMode2() {
- // 获取对象
- SaRequest req = SaHolder.getRequest();
- SaResponse res = SaHolder.getResponse();
- StpLogic stpLogic = ssoClientTemplate.getStpLogic();
-
- // 开始处理
- if(stpLogic.isLogin()) {
- stpLogic.logout(stpLogic.getLoginId());
- }
-
- // 返回
- return ssoLogoutBack(req, res);
- }
-
- /**
- * SSO-Client端:单点注销 [模式三]
- * @return 处理结果
- */
- public Object ssoLogoutByMode3() {
- // 获取对象
- SaRequest req = SaHolder.getRequest();
- SaResponse res = SaHolder.getResponse();
- StpLogic stpLogic = ssoClientTemplate.getStpLogic();
- boolean singleDeviceIdLogout = req.isParam(ssoClientTemplate.paramName.singleDeviceIdLogout, "true");
-
- // 如果未登录,则无需注销
- if( ! stpLogic.isLogin()) {
- return ssoLogoutBack(req, res);
- }
-
- // 调用 sso-server 认证中心单点注销API
- SaLogoutParameter logoutParameter = stpLogic.createSaLogoutParameter();
- if(singleDeviceIdLogout) {
- logoutParameter.setDeviceId(stpLogic.getLoginDeviceId());
- }
- Object centerId = ssoClientTemplate.strategy.convertLoginIdToCenterId.run(stpLogic.getLoginId());
- SaSsoMessage message = ssoClientTemplate.buildSloMessage(centerId, logoutParameter);
- SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
-
- // 校验响应状态码
- if(result.getCode() != null && SaResult.CODE_SUCCESS == result.getCode()) {
- // 极端场景下,sso-server 中心的单点注销可能并不会通知到此 client 端,所以这里需要再补一刀
- if(stpLogic.isLogin()) {
- stpLogic.logout();
- }
- return ssoLogoutBack(req, res);
- } else {
- // 将 sso-server 回应的消息作为异常抛出
- throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30006);
- }
- }
-
/**
* SSO-Client端:单点注销的回调 [模式三]
* @return 处理结果
@@ -265,8 +172,6 @@ public class SaSsoClientProcessor {
Object loginId = req.getParamNotNull(paramName.loginId);
loginId = ssoClientTemplate.strategy.convertCenterIdToLoginId.run(loginId);
String deviceId = req.getParam(paramName.deviceId);
- // String client = req.getParam(paramName.client);
- // String autoLogout = req.getParam(paramName.autoLogout);
// 校验参数签名
if(ssoConfig.getIsCheckSign()) {
@@ -283,7 +188,109 @@ public class SaSsoClientProcessor {
return SaResult.ok("单点注销回调成功");
}
- // 工具方法
+ // 次级方法
+
+ /**
+ * 跳转去 sso-server 认证中心
+ * @return /
+ */
+ public Object _goServerAuth() {
+ // 获取对象
+ SaRequest req = SaHolder.getRequest();
+ SaResponse res = SaHolder.getResponse();
+ SaSsoClientConfig cfg = ssoClientTemplate.getClientConfig();
+ StpLogic stpLogic = ssoClientTemplate.getStpLogic();
+ ParamName paramName = ssoClientTemplate.paramName;
+
+ // 获取参数
+ String back = req.getParam(paramName.back, "/");
+
+ // 如果当前 sso-client 端已经登录,则无需访问 SSO 认证中心,可以直接返回
+ if(stpLogic.isLogin()) {
+ return res.redirect(back);
+ }
+
+ // 获取当前项目的 sso 登录中转页地址,形如:http://sso-client.com/sso/login
+ // 全局配置了就是用全局的,否则使用当前请求的地址
+ String currSsoLoginUrl = cfg.getCurrSsoLogin();
+ if(SaFoxUtil.isEmpty(currSsoLoginUrl)) {
+ currSsoLoginUrl = SaHolder.getRequest().getUrl();
+ }
+ // 构建最终授权地址 url,形如:http://sso-server.com/sso/auth?redirectUrl=http://sso-client.com/sso/login?back=http://sso-client.com
+ String serverAuthUrl = ssoClientTemplate.buildServerAuthUrl(currSsoLoginUrl, back);
+ return res.redirect(serverAuthUrl);
+ }
+
+ /**
+ * 根据认证中心回传的 ticket 进行登录
+ * @return /
+ */
+ public Object _loginByTicket() {
+ // 获取对象
+ SaRequest req = SaHolder.getRequest();
+ SaResponse res = SaHolder.getResponse();
+ StpLogic stpLogic = ssoClientTemplate.getStpLogic();
+ ParamName paramName = ssoClientTemplate.paramName;
+ ApiName apiName = ssoClientTemplate.apiName;
+
+ // 获取参数
+ String back = req.getParam(paramName.back, "/");
+ String ticket = req.getParam(paramName.ticket);
+
+ // 1、校验 ticket,获取 loginId 等数据
+ SaCheckTicketResult ctr = checkTicket(ticket, apiName.ssoLogin);
+ ctr.centerId = ctr.loginId;
+ ctr.loginId = ssoClientTemplate.strategy.convertCenterIdToLoginId.run(ctr.centerId);
+
+ // 2、如果开发者自定义了 ticket 结果值处理函数,则使用自定义的函数
+ if(ssoClientTemplate.strategy.ticketResultHandle != null) {
+ return ssoClientTemplate.strategy.ticketResultHandle.run(ctr, back);
+ }
+
+ // 3、登录并重定向至back地址
+ stpLogic.login(ctr.loginId, new SaLoginParameter()
+ .setTimeout(ctr.remainTokenTimeout)
+ .setDeviceId(ctr.deviceId)
+ );
+ return res.redirect(back);
+ }
+
+ /**
+ * SSO-Client端:单点注销 [模式三]
+ * @return 处理结果
+ */
+ public Object _ssoLogoutByMode3() {
+ // 获取对象
+ SaRequest req = SaHolder.getRequest();
+ SaResponse res = SaHolder.getResponse();
+ StpLogic stpLogic = ssoClientTemplate.getStpLogic();
+ boolean singleDeviceIdLogout = req.isParam(ssoClientTemplate.paramName.singleDeviceIdLogout, "true");
+
+ // 如果未登录,则无需注销
+ if( ! stpLogic.isLogin()) {
+ return _ssoLogoutBack(req, res);
+ }
+
+ // 向 sso-server 认证中心推送消息:单点注销
+ SaLogoutParameter logoutParameter = stpLogic.createSaLogoutParameter();
+ if(singleDeviceIdLogout) {
+ logoutParameter.setDeviceId(stpLogic.getLoginDeviceId());
+ }
+ Object centerId = ssoClientTemplate.strategy.convertLoginIdToCenterId.run(stpLogic.getLoginId());
+ SaSsoMessage message = ssoClientTemplate.buildSloMessage(centerId, logoutParameter);
+ SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
+
+ // 如果 sso-server 响应的状态码非200,代表业务失败,将回应的 msg 字段作为异常抛出
+ if(result.getCode() == null || SaResult.CODE_SUCCESS != result.getCode()) {
+ throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30006);
+ }
+
+ // 极端场景下,sso-server 中心的单点注销可能并不会通知到当前 client 端,所以这里需要再补一刀
+ if(stpLogic.isLogin()) {
+ stpLogic.logout(logoutParameter);
+ }
+ return _ssoLogoutBack(req, res);
+ }
/**
* 封装:校验ticket,取出loginId,如果 ticket 无效则抛出异常 (适用于模式二或模式三)
@@ -294,70 +301,90 @@ public class SaSsoClientProcessor {
*/
public SaCheckTicketResult checkTicket(String ticket, String currUri) {
SaSsoClientConfig cfg = ssoClientTemplate.getClientConfig();
+
+ // 两种模式:
+ // isHttp=true:模式三,使用 http 请求从认证中心校验ticket
+ // isHttp=false:模式二,直连 redis 中校验 ticket
+ if(cfg.getIsHttp()) {
+ return _checkTicketByHttp(ticket, currUri);
+ } else {
+ return _checkTicketByRedis(ticket);
+ }
+ }
+
+ /**
+ * 校验 ticket,http 请求方式
+ * @param ticket /
+ * @param currUri /
+ * @return /
+ */
+ public SaCheckTicketResult _checkTicketByHttp(String ticket, String currUri) {
+ SaSsoClientConfig cfg = ssoClientTemplate.getClientConfig();
ApiName apiName = ssoClientTemplate.apiName;
ParamName paramName = ssoClientTemplate.paramName;
- // --------- 两种模式
- if(cfg.getIsHttp()) {
- // q1、使用模式三:使用 http 请求从认证中心校验ticket
-
- // 计算当前 sso-client 的单点注销回调地址
- String ssoLogoutCall = null;
- if(cfg.getRegLogoutCall()) {
- // 如果配置了回调地址,就使用配置的值:
- if(SaFoxUtil.isNotEmpty(cfg.getCurrSsoLogoutCall())) {
- ssoLogoutCall = cfg.getCurrSsoLogoutCall();
- }
- // 如果提供了当前 uri,则根据此值来计算:
- else if(SaFoxUtil.isNotEmpty(currUri)) {
- ssoLogoutCall = SaHolder.getRequest().getUrl().replace(currUri, apiName.ssoLogoutCall);
- }
- // 否则视为不注册单点注销回调地址
- else {
- }
+ // 计算当前 sso-client 的单点注销回调地址
+ String ssoLogoutCall = null;
+ if(cfg.getRegLogoutCall()) {
+ // 如果配置了回调地址,就使用配置的值:
+ if(SaFoxUtil.isNotEmpty(cfg.getCurrSsoLogoutCall())) {
+ ssoLogoutCall = cfg.getCurrSsoLogoutCall();
}
-
- // 发起请求
- SaSsoMessage message = ssoClientTemplate.buildCheckTicketMessage(ticket, ssoLogoutCall);
- SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
-
- // 校验
- if(result.getCode() != null && result.getCode() == SaResult.CODE_SUCCESS) {
-
- SaCheckTicketResult ctr = new SaCheckTicketResult();
- ctr.loginId = result.get(paramName.loginId);
- ctr.tokenValue = result.get(paramName.tokenValue, String.class);
- ctr.deviceId = result.get(paramName.deviceId, String.class);
- ctr.remainTokenTimeout = result.get(paramName.remainTokenTimeout, Long.class);
- ctr.remainSessionTimeout = result.get(paramName.remainSessionTimeout, Long.class);
- ctr.result = result;
-
- return ctr;
- } else {
- // 将 sso-server 回应的消息作为异常抛出
- throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30005);
+ // 如果提供了当前 uri,则根据此值来计算:
+ else if(SaFoxUtil.isNotEmpty(currUri)) {
+ ssoLogoutCall = SaHolder.getRequest().getUrl().replace(currUri, apiName.ssoLogoutCall);
+ }
+ // 否则视为不注册单点注销回调地址
+ else {
}
- } else {
- // q2、使用模式二:直连Redis校验ticket
- // 注意此处调用了 SaSsoServerProcessor 处理器里的方法,
- // 这意味着如果你的 sso-server 端重写了 SaSsoServerProcessor 里的部分方法,
- // 而在当前 sso-client 没有按照相应格式重写 SaSsoClientProcessor 里的方法,
- // 可能会导致调用失败(注意是可能,而非一定),
- // 解决方案为:在当前 sso-client 端也按照 sso-server 端的格式重写 SaSsoClientProcessor 里的方法
-
- StpLogic stpLogic = ssoClientTemplate.getStpLogic();
- TicketModel ticketModel = SaSsoServerProcessor.instance.ssoServerTemplate.checkTicketParamAndDelete(ticket, ssoClientTemplate.getClient());
-
- SaCheckTicketResult ctr = new SaCheckTicketResult();
- ctr.loginId = ticketModel.getLoginId();
- ctr.tokenValue = ticketModel.getTokenValue();
- ctr.deviceId = stpLogic.getLoginDeviceIdByToken(ticketModel.getTokenValue());
- ctr.remainTokenTimeout = stpLogic.getTokenTimeout(ticketModel.getTokenValue());
- ctr.remainSessionTimeout = stpLogic.getSessionTimeoutByLoginId(ticketModel.getLoginId());
- ctr.result = null;
-
- return ctr;
}
+
+ // 发起请求
+ SaSsoMessage message = ssoClientTemplate.buildCheckTicketMessage(ticket, ssoLogoutCall);
+ SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
+
+ // 如果 sso-server 响应的状态码非200,代表业务失败,将回应的 msg 字段作为异常抛出
+ if(result.getCode() == null || result.getCode() != SaResult.CODE_SUCCESS) {
+ throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30005);
+ }
+
+ // 构建返回结果
+ SaCheckTicketResult ctr = new SaCheckTicketResult();
+ ctr.loginId = result.get(paramName.loginId);
+ ctr.tokenValue = result.get(paramName.tokenValue, String.class);
+ ctr.deviceId = result.get(paramName.deviceId, String.class);
+ ctr.remainTokenTimeout = result.get(paramName.remainTokenTimeout, Long.class);
+ ctr.remainSessionTimeout = result.get(paramName.remainSessionTimeout, Long.class);
+ ctr.result = result;
+
+ return ctr;
+ }
+
+ /**
+ * 校验 ticket,直连 redis 方式
+ * @param ticket /
+ * @return /
+ */
+ public SaCheckTicketResult _checkTicketByRedis(String ticket) {
+ // 直连 redis 校验 ticket
+ // 注意此处调用了 SaSsoServerProcessor 处理器里的方法,
+ // 这意味着如果你的 sso-server 端重写了 SaSsoServerProcessor 里的部分方法,
+ // 而在当前 sso-client 没有按照相应格式重写 SaSsoClientProcessor 里的方法,
+ // 可能会导致调用失败(注意是可能,而非一定,主要取决于你是否改变了数据读写格式),
+ // 解决方案为:在当前 sso-client 端也按照 sso-server 端的格式重写 SaSsoClientProcessor 里的方法
+
+ StpLogic stpLogic = ssoClientTemplate.getStpLogic();
+ TicketModel ticketModel = SaSsoServerProcessor.instance.ssoServerTemplate.checkTicketParamAndDelete(ticket, ssoClientTemplate.getClient());
+
+ SaCheckTicketResult ctr = new SaCheckTicketResult();
+ ctr.loginId = ticketModel.getLoginId();
+ ctr.tokenValue = ticketModel.getTokenValue();
+ ctr.deviceId = stpLogic.getLoginDeviceIdByToken(ticketModel.getTokenValue());
+ ctr.remainTokenTimeout = stpLogic.getTokenTimeout(ticketModel.getTokenValue());
+ ctr.remainSessionTimeout = stpLogic.getSessionTimeoutByLoginId(ticketModel.getLoginId());
+ ctr.result = null;
+
+ return ctr;
}
/**
@@ -366,10 +393,8 @@ public class SaSsoClientProcessor {
* @param res SaResponse对象
* @return 返回结果
*/
- public Object ssoLogoutBack(SaRequest req, SaResponse res) {
+ public Object _ssoLogoutBack(SaRequest req, SaResponse res) {
return SaSsoProcessorHelper.ssoLogoutBack(req, res, ssoClientTemplate.paramName);
}
-
-
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoProcessorHelper.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoProcessorHelper.java
index 5aff4582..ba967566 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoProcessorHelper.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoProcessorHelper.java
@@ -17,8 +17,8 @@ package cn.dev33.satoken.sso.processor;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
-import cn.dev33.satoken.sso.util.SaSsoConsts;
import cn.dev33.satoken.sso.name.ParamName;
+import cn.dev33.satoken.sso.util.SaSsoConsts;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
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 3d2e4472..3d180a2e 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
@@ -57,13 +57,13 @@ public class SaSsoServerProcessor {
/**
* 分发 Server 端所有请求
+ *
* @return 处理结果
*/
public Object dister() {
// 获取对象
SaRequest req = SaHolder.getRequest();
- SaSsoServerConfig cfg = ssoServerTemplate.getServerConfig();
ApiName apiName = ssoServerTemplate.apiName;
// ------------------ 路由分发 ------------------
@@ -104,36 +104,44 @@ public class SaSsoServerProcessor {
StpLogic stpLogic = ssoServerTemplate.getStpLogic();
ParamName paramName = ssoServerTemplate.paramName;
- // ---------- 此处有两种情况分开处理:
- // ---- 情况1:在SSO认证中心尚未登录,需要先去登录
+ // 两种情况:
+ // 情况1:在 SSO 认证中心尚未登录,需要显示登录视图,去登录
+ // 情况2:在 SSO 认证中心已经登录,需要重定向回 Client 端
+
+ // 情况1,显示登录视图
if( ! stpLogic.isLogin()) {
return ssoServerTemplate.strategy.notLoginView.get();
}
- // ---- 情况2:在SSO认证中心已经登录,需要重定向回 Client 端,而这又分为两种方式:
+
+ // 情况2,开始跳转
String mode = req.getParam(paramName.mode, SaSsoConsts.MODE_TICKET);
String redirect = req.getParam(paramName.redirect);
String client = req.getParam(paramName.client);
- // 若 redirect 为空,则选择 homeRoute,若 homeRoute 也为空,则抛出异常
- if(SaFoxUtil.isEmpty(redirect)) {
- if(SaFoxUtil.isEmpty(cfg.getHomeRoute())) {
- throw new SaSsoException("未指定 redirect 参数,也未配置 homeRoute 路由,无法完成重定向操作").setCode(SaSsoErrorCode.CODE_30014);
- }
- ssoServerTemplate.strategy.jumpToRedirectUrlNotice.run(cfg.getHomeRoute());
- return res.redirect(cfg.getHomeRoute());
- }
-
+ // 构建最终重定向地址
String redirectUrl = SaSugar.get(() -> {
- // 方式1:直接重定向回Client端 (mode=simple)
+
+ // 若 redirect 参数为空,说明用户并不是从 client 重定向来的,而是直接访问的 http://sso-server.com/sso/auth 地址
+ // 此时需要跳转到配置的 homeRoute 路由上,
+ // 若 homeRoute 也为空,则没有明确的跳转地址了,需要抛出异常
+ if(SaFoxUtil.isEmpty(redirect)) {
+ if(SaFoxUtil.isEmpty(cfg.getHomeRoute())) {
+ throw new SaSsoException("未指定 redirect 参数,也未配置 homeRoute 路由,无法完成重定向操作").setCode(SaSsoErrorCode.CODE_30014);
+ }
+ return cfg.getHomeRoute();
+ }
+
+ // 方式1:直接重定向回Client端 (mode=simple,一般是模式一)
if(mode.equals(SaSsoConsts.MODE_SIMPLE)) {
ssoServerTemplate.checkRedirectUrl(client, redirect);
return redirect;
} else {
- // 方式2:带着 ticket 参数重定向回Client端 (mode=ticket)
+ // 方式2:带着 ticket 参数重定向回Client端 (mode=ticket,一般是模式二、三)
// 构建并跳转
String _redirectUrl = ssoServerTemplate.buildRedirectUrl(client, redirect, stpLogic.getLoginId(), stpLogic.getTokenValue());
- // 构建成功,说明 redirect 地址合法,此时需要更新一下该账号的Session有效期
+
+ // 构建成功,说明 redirect 地址合法,此时需要更新一下当前 token 有效期
if(cfg.getAutoRenewTimeout()) {
stpLogic.renewTimeout(stpLogic.getConfigOrGlobal().getTimeout());
}
@@ -151,13 +159,14 @@ public class SaSsoServerProcessor {
* @return 处理结果
*/
public Object ssoDoLogin() {
- // 获取对象
+ // 获取参数
SaRequest req = SaHolder.getRequest();
- SaSsoServerConfig cfg = ssoServerTemplate.getServerConfig();
ParamName paramName = ssoServerTemplate.paramName;
+ String name = req.getParam(paramName.name);
+ String pwd = req.getParam(paramName.pwd);
// 处理
- return ssoServerTemplate.strategy.doLoginHandle.apply(req.getParam(paramName.name), req.getParam(paramName.pwd));
+ return ssoServerTemplate.strategy.doLoginHandle.apply(name, pwd);
}
/**
@@ -168,14 +177,15 @@ public class SaSsoServerProcessor {
// 获取对象
SaRequest req = SaHolder.getRequest();
SaResponse res = SaHolder.getResponse();
- Object loginId = ssoServerTemplate.getStpLogic().getLoginIdDefaultNull();
+ StpLogic stpLogic = ssoServerTemplate.getStpLogic();
+ Object loginId = stpLogic.getLoginIdDefaultNull();
boolean singleDeviceIdLogout = req.isParam(ssoServerTemplate.paramName.singleDeviceIdLogout, "true");
// 单点注销
if(SaFoxUtil.isNotEmpty(loginId)) {
- SaLogoutParameter logoutParameter = ssoServerTemplate.getStpLogic().createSaLogoutParameter();
+ SaLogoutParameter logoutParameter = stpLogic.createSaLogoutParameter();
if(singleDeviceIdLogout) {
- logoutParameter.setDeviceId(ssoServerTemplate.getStpLogic().getLoginDeviceId());
+ logoutParameter.setDeviceId(stpLogic.getLoginDeviceId());
}
ssoServerTemplate.ssoLogout(loginId, logoutParameter);
}
@@ -202,7 +212,7 @@ public class SaSsoServerProcessor {
return SaResult.error("无效 client 标识:" + client);
}
- // 3、校验签名
+ // 3、校验参数签名
Map paramMap = req.getParamMap();
if(ssoServerConfig.getIsCheckSign()) {
ssoServerTemplate.getSignTemplate(client).checkParamMap(paramMap);
@@ -210,10 +220,10 @@ public class SaSsoServerProcessor {
SaSsoManager.printNoCheckSignWarningByRuntime();
}
- // 处理消息
+ // 4、处理消息
SaSsoMessage message = new SaSsoMessage(paramMap);
if( ! ssoServerTemplate.messageHolder.hasHandle(message.getType())) {
- return SaResult.error("未能找到消息处理器: " + message.getType());
+ return SaResult.error("未能找到消息处理器:" + message.getType());
}
return ssoServerTemplate.handleMessage(message);
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoClientStrategy.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoClientStrategy.java
index 6a24937e..e205ce3c 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoClientStrategy.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoClientStrategy.java
@@ -19,6 +19,9 @@ import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.fun.SaParamRetFunction;
import cn.dev33.satoken.sso.function.SendHttpFunction;
import cn.dev33.satoken.sso.function.TicketResultHandleFunction;
+import cn.dev33.satoken.util.SaResult;
+
+import java.util.Map;
/**
* Sa-Token SSO Client 相关策略
@@ -62,4 +65,16 @@ public class SaSsoClientStrategy {
return loginId;
};
+ /**
+ * 发送 Http 请求,并将响应结果转换为 SaResult
+ *
+ * @param url 请求地址
+ * @return 返回的结果
+ */
+ public SaResult requestAsSaResult(String url) {
+ String body = 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/strategy/SaSsoServerStrategy.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoServerStrategy.java
index 90f41d9b..4c9c2197 100644
--- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoServerStrategy.java
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/strategy/SaSsoServerStrategy.java
@@ -23,6 +23,8 @@ import cn.dev33.satoken.sso.function.NotLoginViewFunction;
import cn.dev33.satoken.sso.function.SendHttpFunction;
import cn.dev33.satoken.util.SaResult;
+import java.util.Map;
+
/**
* Sa-Token SSO Server 相关策略
*
@@ -66,4 +68,16 @@ public class SaSsoServerStrategy {
return result;
};
+ /**
+ * 发送 Http 请求,并将响应结果转换为 SaResult
+ *
+ * @param url 请求地址
+ * @return 返回的结果
+ */
+ public SaResult requestAsSaResult(String url) {
+ String body = 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/SaSsoClientTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientTemplate.java
index d7e03dd1..85dc3366 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
@@ -33,7 +33,7 @@ import cn.dev33.satoken.util.SaResult;
import java.util.Map;
/**
- * Sa-Token SSO 模板方法类 (Client端)
+ * SSO 模板方法类 (Client端)
*
* @author click33
* @since 1.38.0
@@ -50,10 +50,11 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
}
- // ------------------- SSO 模式三相关 -------------------
+ // ------------------- getData 相关 -------------------
/**
* 根据配置的 getData 地址,查询数据
+ *
* @param paramMap 查询参数
* @return 查询结果
*/
@@ -64,6 +65,7 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
/**
* 根据自定义 path 地址,查询数据 (此方法需要配置 sa-token.sso.server-url 地址)
+ *
* @param path 自定义 path
* @param paramMap 查询参数
* @return 查询结果
@@ -73,44 +75,6 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
return strategy.sendHttp.apply(url);
}
- // ---------------------- 构建URL ----------------------
-
- /**
- * 构建URL:Server端 单点登录地址
- * @param clientLoginUrl Client端登录地址
- * @param back 回调路径
- * @return [SSO-Server端-认证地址 ]
- */
- public String buildServerAuthUrl(String clientLoginUrl, String back) {
- SaSsoClientConfig ssoConfig = getClientConfig();
-
- // 服务端认证地址
- String serverUrl = ssoConfig.splicingAuthUrl();
-
- // 拼接客户端标识
- String client = getClient();
- if(SaFoxUtil.isNotEmpty(client)) {
- serverUrl = SaFoxUtil.joinParam(serverUrl, paramName.client, client);
- }
-
- // 对back地址编码
- back = (back == null ? "" : back);
- back = SaFoxUtil.encodeUrl(back);
-
- // 开始拼接 sso 统一认证地址,形如:serverAuthUrl = http://xxx.com?redirectUrl=xxx.com?back=xxx.com
-
- /*
- * 部分 Servlet 版本 request.getRequestURL() 返回的 url 带有 query 参数,形如:http://domain.com?id=1,
- * 如果不加判断会造成最终生成的 serverAuthUrl 带有双 back 参数 ,这个 if 判断正是为了解决此问题
- */
- if( ! clientLoginUrl.contains(paramName.back + "=") ) {
- clientLoginUrl = SaFoxUtil.joinParam(clientLoginUrl, paramName.back, back);
- }
-
- // 返回
- return SaFoxUtil.joinParam(serverUrl, paramName.redirect, clientLoginUrl);
- }
-
/**
* 构建URL:Server端 getData 地址,带签名等参数
* @param paramMap 查询参数
@@ -146,55 +110,49 @@ 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, getClient());
- message.set(paramName.ticket, ticket);
- message.set(paramName.ssoLogoutCall, ssoLogoutCallUrl);
- return message;
- }
+
+ // ---------------------- 构建交互地址 ----------------------
/**
- * 构建消息:单点注销
- *
- * @param loginId 要注销的账号 id
- * @param logoutParameter 单点注销
- * @return 单点注销URL
+ * 构建URL:Server端 单点登录授权地址,
+ *
形如:http://sso-server.com/sso/auth?redirectUrl=http://sso-client.com/sso/login?back=http://sso-client.com
+ * @param clientLoginUrl Client端登录地址
+ * @param back 回调路径
+ * @return [SSO-Server端-认证地址 ]
*/
- public SaSsoMessage buildSloMessage(Object loginId, SaLogoutParameter logoutParameter) {
+ public String buildServerAuthUrl(String clientLoginUrl, String back) {
SaSsoClientConfig ssoConfig = getClientConfig();
- SaSsoMessage message = new SaSsoMessage();
- message.setType(SaSsoConsts.MESSAGE_SIGNOUT);
- message.set(paramName.client, getClient());
- message.set(paramName.loginId, loginId);
- message.set(paramName.deviceId, logoutParameter.getDeviceId());
- return message;
+
+ // 服务端认证地址
+ String serverUrl = ssoConfig.splicingAuthUrl();
+
+ // 拼接客户端标识
+ String client = getClient();
+ if(SaFoxUtil.isNotEmpty(client)) {
+ serverUrl = SaFoxUtil.joinParam(serverUrl, paramName.client, client);
+ }
+
+ // 对back地址编码
+ back = (back == null ? "" : back);
+ back = SaFoxUtil.encodeUrl(back);
+
+ // 开始拼接 sso 统一认证地址,形如:serverAuthUrl = http://xxx.com?redirectUrl=xxx.com?back=xxx.com
+
+ /*
+ * 部分 Servlet 版本 request.getRequestURL() 返回的 url 带有 query 参数,形如:http://domain.com?id=1,
+ * 如果不加判断会造成最终生成的 serverAuthUrl 带有双 back 参数 ,这个 if 判断正是为了解决此问题
+ */
+ if( ! clientLoginUrl.contains(paramName.back + "=") ) {
+ clientLoginUrl = SaFoxUtil.joinParam(clientLoginUrl, paramName.back, back);
+ }
+
+ // 返回
+ return SaFoxUtil.joinParam(serverUrl, paramName.redirect, clientLoginUrl);
}
// ------------------- 消息推送 -------------------
- /**
- * 发送 Http 请求,并将响应结果转换为 SaResult
- *
- * @param url 请求地址
- * @return 返回的结果
- */
- public SaResult requestAsSaResult(String url) {
- String body = strategy.sendHttp.apply(url);
- Map map = SaManager.getSaJsonTemplate().jsonToMap(body);
- return new SaResult(map);
- }
-
/**
* 向 sso-server 推送消息
*
@@ -230,6 +188,40 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
return new SaResult(map);
}
+ /**
+ * 构建消息:校验 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, getClient());
+ message.set(paramName.ticket, ticket);
+ message.set(paramName.ssoLogoutCall, ssoLogoutCallUrl);
+ return message;
+ }
+
+ /**
+ * 构建消息:单点注销
+ *
+ * @param loginId 要注销的账号 id
+ * @param logoutParameter 单点注销
+ * @return 单点注销URL
+ */
+ public SaSsoMessage buildSloMessage(Object loginId, SaLogoutParameter logoutParameter) {
+ SaSsoClientConfig ssoConfig = getClientConfig();
+ SaSsoMessage message = new SaSsoMessage();
+ message.setType(SaSsoConsts.MESSAGE_SIGNOUT);
+ message.set(paramName.client, getClient());
+ message.set(paramName.loginId, loginId);
+ message.set(paramName.deviceId, logoutParameter.getDeviceId());
+ return message;
+ }
+
// ------------------- Bean 对象获取 -------------------
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientUtil.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientUtil.java
new file mode 100644
index 00000000..b9594569
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoClientUtil.java
@@ -0,0 +1,127 @@
+/*
+ * 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.template;
+
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
+import cn.dev33.satoken.stp.parameter.SaLogoutParameter;
+import cn.dev33.satoken.util.SaResult;
+
+import java.util.Map;
+
+/**
+ * SSO 模板方法类 (Client端)
+ *
+ * @author click33
+ * @since 1.38.0
+ */
+public class SaSsoClientUtil extends SaSsoTemplate {
+
+ private SaSsoClientUtil() {
+ }
+
+ /**
+ * 返回底层使用的 SaSsoClientTemplate 对象
+ * @return /
+ */
+ public static SaSsoClientTemplate getSsoTemplate() {
+ return SaSsoClientProcessor.instance.ssoClientTemplate;
+ }
+
+
+ // ------------------- getData 相关 -------------------
+
+ /**
+ * 根据配置的 getData 地址,查询数据
+ *
+ * @param paramMap 查询参数
+ * @return 查询结果
+ */
+ public static Object getData(Map paramMap) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.getData(paramMap);
+ }
+
+ /**
+ * 根据自定义 path 地址,查询数据 (此方法需要配置 sa-token.sso.server-url 地址)
+ *
+ * @param path 自定义 path
+ * @param paramMap 查询参数
+ * @return 查询结果
+ */
+ public static Object getData(String path, Map paramMap) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.getData(path, paramMap);
+ }
+
+
+ // ---------------------- 构建交互地址 ----------------------
+
+ /**
+ * 构建URL:Server端 单点登录授权地址,
+ *
形如:http://sso-server.com/sso/auth?redirectUrl=http://sso-client.com/sso/login?back=http://sso-client.com
+ * @param clientLoginUrl Client端登录地址
+ * @param back 回调路径
+ * @return [SSO-Server端-认证地址 ]
+ */
+ public static String buildServerAuthUrl(String clientLoginUrl, String back) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.buildServerAuthUrl(clientLoginUrl, back);
+ }
+
+
+ // ------------------- 消息推送 -------------------
+
+ /**
+ * 向 sso-server 推送消息
+ *
+ * @param message /
+ * @return /
+ */
+ public static String pushMessage(SaSsoMessage message) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.pushMessage(message);
+ }
+
+ /**
+ * 向 sso-server 推送消息,并将返回值转为 SaResult
+ *
+ * @param message /
+ * @return /
+ */
+ public static SaResult pushMessageAsSaResult(SaSsoMessage message) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.pushMessageAsSaResult(message);
+ }
+
+ /**
+ * 构建消息:校验 ticket
+ *
+ * @param ticket ticket码
+ * @param ssoLogoutCallUrl 单点注销时的回调URL
+ * @return 构建完毕的URL
+ */
+ public static SaSsoMessage buildCheckTicketMessage(String ticket, String ssoLogoutCallUrl) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.buildCheckTicketMessage(ticket, ssoLogoutCallUrl);
+ }
+
+ /**
+ * 构建消息:单点注销
+ *
+ * @param loginId 要注销的账号 id
+ * @param logoutParameter 单点注销
+ * @return 单点注销URL
+ */
+ public static SaSsoMessage buildSloMessage(Object loginId, SaLogoutParameter logoutParameter) {
+ return SaSsoClientProcessor.instance.ssoClientTemplate.buildSloMessage(loginId, logoutParameter);
+ }
+
+}
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 9306ae8e..855b7ccd 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
@@ -39,7 +39,7 @@ import cn.dev33.satoken.util.SaResult;
import java.util.*;
/**
- * Sa-Token SSO 模板方法类 (Server端)
+ * SSO 模板方法类 (Server端)
*
* @author click33
* @since 1.38.0
@@ -58,40 +58,17 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
// ---------------------- Ticket 操作 ----------------------
+ // 增删改
+
/**
* 保存 Ticket
* @param ticketModel /
*/
public void saveTicket(TicketModel ticketModel) {
long ticketTimeout = getServerConfig().getTicketTimeout();
- SaManager.getSaTokenDao().setObject(splicingTicketSaveKey(ticketModel.getTicket()), ticketModel, ticketTimeout);
+ SaManager.getSaTokenDao().setObject(splicingTicketModelSaveKey(ticketModel.getTicket()), ticketModel, ticketTimeout);
}
- /**
- * 保存 Ticket 索引 (id 反查 ticket)
- *
- * @param client 应用端
- * @param ticket ticket码
- * @param loginId 账号id
- */
- public void saveTicketIndex(String client, Object loginId, String ticket) {
- long ticketTimeout = getServerConfig().getTicketTimeout();
- SaManager.getSaTokenDao().set(splicingTicketIndexKey(client, loginId), String.valueOf(ticket), ticketTimeout);
- }
-
-// /**
-// * 保存 Ticket 关联的 client
-// * @param ticket ticket码
-// * @param client 客户端标识
-// */
-// public void saveTicketToClient(String ticket, String client) {
-// if(SaFoxUtil.isEmpty(client)) {
-// return;
-// }
-// long ticketTimeout = getServerConfig().getTicketTimeout();
-// SaManager.getSaTokenDao().set(splicingTicketToClientSaveKey(ticket), client, ticketTimeout);
-// }
-
/**
* 删除 Ticket
* @param ticket Ticket码
@@ -100,36 +77,59 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
if(ticket == null) {
return;
}
- SaManager.getSaTokenDao().deleteObject(splicingTicketSaveKey(ticket));
+ SaManager.getSaTokenDao().deleteObject(splicingTicketModelSaveKey(ticket));
}
/**
- * 删除 Ticket索引
+ * 根据参数创建一个 ticket 码
*
- * @param client 应用标识
- * @param loginId 账号id
+ * @param client 客户端标识
+ * @param loginId 账号 id
+ * @param tokenValue 会话 Token
+ * @return Ticket码
*/
- public void deleteTicketIndex(String client, Object loginId) {
- if(loginId == null) {
- return;
- }
- SaManager.getSaTokenDao().delete(splicingTicketIndexKey(client, loginId));
+ public TicketModel createTicket(String client, Object loginId, String tokenValue) {
+ TicketModel ticketModel = new TicketModel();
+ ticketModel.setTicket(randomTicket(loginId));
+ ticketModel.setClient(client);
+ ticketModel.setLoginId(loginId);
+ ticketModel.setTokenValue(tokenValue);
+ return ticketModel;
}
-// /**
-// * 删除 Ticket 关联的 client
-// *
-// * @param ticket Ticket码
-// */
-// public void deleteTicketToClient(String ticket) {
-// if(ticket == null) {
-// return;
-// }
-// SaManager.getSaTokenDao().delete(splicingTicketToClientSaveKey(ticket));
-// }
+ /**
+ * 根据参数创建一个 ticket 码,并保存
+ *
+ * @param client 客户端标识
+ * @param loginId 账号 id
+ * @param tokenValue 会话 Token
+ * @return Ticket码
+ */
+ public String createTicketAndSave(String client, Object loginId, String tokenValue) {
+ // 创建
+ TicketModel ticketModel = createTicket(client, loginId, tokenValue);
+
+ // 保存
+ saveTicket(ticketModel);
+ saveTicketIndex(client, loginId, ticketModel.getTicket());
+
+ // 返回
+ return ticketModel.getTicket();
+ }
/**
- * 查询 ticket ,如果 ticket 码无效则返回 null
+ * 随机一个 Ticket 码
+ * @param loginId 账号id
+ * @return Ticket 码
+ */
+ public String randomTicket(Object loginId) {
+ return SaFoxUtil.getRandomString(64);
+ }
+
+ // 查
+
+ /**
+ * 查询 ticket ,如果 ticket 无效则返回 null
*
* @param ticket Ticket码
* @return 账号id
@@ -138,7 +138,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
if(SaFoxUtil.isEmpty(ticket)) {
return null;
}
- return SaManager.getSaTokenDao().getObject(splicingTicketSaveKey(ticket), TicketModel.class);
+ return SaManager.getSaTokenDao().getObject(splicingTicketModelSaveKey(ticket), TicketModel.class);
}
/**
@@ -165,57 +165,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
return SaFoxUtil.getValueByType(getLoginId(ticket), cs);
}
- /**
- * 查询 指定 client、loginId 其所属的 ticket 值
- *
- * @param client 应用
- * @param loginId 账号id
- * @return Ticket值
- */
- public String getTicketValue(String client, Object loginId) {
- if(loginId == null) {
- return null;
- }
- return SaManager.getSaTokenDao().get(splicingTicketIndexKey(client, loginId));
- }
-
-// /**
-// * 查询 ticket 关联的 client,如果 ticket 码无效则返回 null
-// * @param ticket Ticket码
-// * @return 账号id
-// */
-// public String getTicketToClient(String ticket) {
-// if(SaFoxUtil.isEmpty(ticket)) {
-// return null;
-// }
-// return SaManager.getSaTokenDao().get(splicingTicketToClientSaveKey(ticket));
-// }
-
- //
- /**
- * 根据参数创建一个 ticket 码
- *
- * @param client 客户端标识
- * @param loginId 账号 id
- * @param tokenValue 会话 Token
- * @return Ticket码
- */
- public String createTicket(String client, Object loginId, String tokenValue) {
- // 创建 Ticket
- String ticket = randomTicket(loginId);
- TicketModel ticketModel = new TicketModel();
- ticketModel.setTicket(ticket);
- ticketModel.setClient(client);
- ticketModel.setLoginId(loginId);
- ticketModel.setTokenValue(tokenValue);
-
- // 保存 Ticket
- saveTicket(ticketModel);
- saveTicketIndex(client, loginId, ticket);
-
- // 返回 Ticket
- return ticket;
- }
+ // 校验
/**
* 校验 Ticket,无效 ticket 会抛出异常
@@ -271,13 +221,45 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
return ticketModel;
}
+ // ticket 索引
+
/**
- * 随机一个 Ticket码
+ * 保存 Ticket 索引 (id 反查 ticket)
+ *
+ * @param client 应用端
+ * @param ticket ticket码
* @param loginId 账号id
- * @return Ticket码
*/
- public String randomTicket(Object loginId) {
- return SaFoxUtil.getRandomString(64);
+ public void saveTicketIndex(String client, Object loginId, String ticket) {
+ long ticketTimeout = getServerConfig().getTicketTimeout();
+ SaManager.getSaTokenDao().set(splicingTicketIndexKey(client, loginId), String.valueOf(ticket), ticketTimeout);
+ }
+
+ /**
+ * 删除 Ticket 索引
+ *
+ * @param client 应用标识
+ * @param loginId 账号id
+ */
+ public void deleteTicketIndex(String client, Object loginId) {
+ if(loginId == null) {
+ return;
+ }
+ SaManager.getSaTokenDao().delete(splicingTicketIndexKey(client, loginId));
+ }
+
+ /**
+ * 查询 指定 client、loginId 其所属的 ticket 值
+ *
+ * @param client 应用
+ * @param loginId 账号id
+ * @return Ticket值
+ */
+ public String getTicketValue(String client, Object loginId) {
+ if(loginId == null) {
+ return null;
+ }
+ return SaManager.getSaTokenDao().get(splicingTicketIndexKey(client, loginId));
}
@@ -289,8 +271,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
* @return /
*/
public List getClients() {
- Map clients = getServerConfig().getClients();
- return new ArrayList<>(clients.values());
+ return new ArrayList<>(getServerConfig().getClients().values());
}
/**
@@ -351,7 +332,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
List list = new ArrayList<>();
List clients = getClients();
for(SaSsoClientModel scm : clients) {
- if (scm.isValidNoticeUrl()) {
+ if (scm.getIsPush()) {
list.add(scm);
}
}
@@ -379,14 +360,15 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
deleteTicket(getTicketValue(client, loginId));
// 创建 新Ticket
- String ticket = createTicket(client, loginId, tokenValue);
+ String ticket = createTicketAndSave(client, loginId, tokenValue);
- // 构建 授权重定向地址 (Server端 根据此地址向 Client端 下放Ticket)
+ // 构建 授权重定向地址 (Server端 根据此地址向 Client端 下放 Ticket)
return SaFoxUtil.joinParam(encodeBackParam(redirect), paramName.ticket, ticket);
}
/**
- * 对url中的back参数进行URL编码, 解决超链接重定向后参数丢失的bug
+ * 对 url 中的 back 参数进行 URL 编码, 解决超链接重定向后参数丢失的 bug
+ *
* @param url url
* @return 编码过后的url
*/
@@ -412,7 +394,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
}
/**
- * 校验重定向url合法性
+ * 校验重定向 url 合法性
*
* @param client 应用标识
* @param url 下放ticket的url地址
@@ -513,7 +495,8 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
// ------------------- 单点注销 -------------------
/**
- * 为指定账号 id 注册单点注销回调信息(模式三)
+ * 为指定账号 id 注册应用接入信息(模式三)
+ *
* @param loginId 账号id
* @param client 指定客户端标识,可为null
* @param sloCallbackUrl 单点注销时的回调URL
@@ -539,7 +522,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
for (;;) {
if(scmList.size() > maxRegClient) {
SaSsoClientInfo removeScm = scmList.remove(0);
- notifyClientLogout(loginId, null, removeScm, true);
+ notifyClientLogout(loginId, null, removeScm, true, true);
} else {
break;
}
@@ -591,7 +574,6 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
public void ssoLogout(Object loginId, SaLogoutParameter logoutParameter) {
// 1、消息推送:单点注销
- // TODO 需要把对应的 SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_ 记录也删掉
pushToAllClientByLogoutCall(loginId, logoutParameter);
// 2、SaSession 挂载的 Client 端注销会话
@@ -601,7 +583,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
}
List scmList = session.get(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, ArrayList::new);
scmList.forEach(scm -> {
- notifyClientLogout(loginId, logoutParameter.getDeviceId(), scm, false);
+ notifyClientLogout(loginId, logoutParameter.getDeviceId(), scm, false, false);
});
// 3、Server 端本身注销
@@ -614,17 +596,22 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
* @param deviceId 指定设备 id
* @param scm 客户端信息对象
* @param autoLogout 是否为超过 maxRegClient 的自动注销
+ * @param isPushWork 如果该 client 没有注册注销回调地址,是否使用 push 消息的方式进行注销回调通知
*/
- public void notifyClientLogout(Object loginId, String deviceId, SaSsoClientInfo scm, boolean autoLogout) {
+ public void notifyClientLogout(Object loginId, String deviceId, SaSsoClientInfo scm, boolean autoLogout, boolean isPushWork) {
// 如果给个null值,不进行任何操作
if(scm == null || scm.mode != SaSsoConsts.SSO_MODE_3) {
return;
}
- // 如果此 Client 并没有注册 单点登录 回调地址,则立即返回
+ // 如果此 Client 并没有注册 单点注销 回调地址
String sloCallUrl = scm.getSloCallbackUrl();
if(SaFoxUtil.isEmpty(sloCallUrl)) {
+ // TODO 代码有效性待验证
+ if(isPushWork && SaFoxUtil.isNotEmpty(scm.getClient())) {
+ pushToClientByLogoutCall(getClient(scm.getClient()), loginId, getStpLogic().createSaLogoutParameter());
+ }
return;
}
@@ -646,18 +633,6 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
// ------------------- 消息推送 -------------------
- /**
- * 发送 Http 请求,并将响应结果转换为 SaResult
- *
- * @param url 请求地址
- * @return 返回的结果
- */
- public SaResult requestAsSaResult(String url) {
- String body = strategy.sendHttp.apply(url);;
- Map map = SaManager.getSaJsonTemplate().jsonToMap(body);
- return new SaResult(map);
- }
-
/**
* 向指定 Client 推送消息
* @param clientModel /
@@ -666,7 +641,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
*/
public String pushMessage(SaSsoClientModel clientModel, SaSsoMessage message) {
message.checkType();
- String noticeUrl = clientModel.splicingNoticeUrl();
+ String noticeUrl = clientModel.splicingPushUrl();
String paramsStr = getSignTemplate(clientModel.getClient()).addSignParamsAndJoin(message);
String finalUrl = SaFoxUtil.joinParam(noticeUrl, paramsStr);
return strategy.sendHttp.apply(finalUrl);
@@ -714,8 +689,8 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
* @param message /
*/
public void pushToAllClient(SaSsoMessage message) {
- List mode3Clients = getNeedPushClients();
- for (SaSsoClientModel client : mode3Clients) {
+ List needPushClients = getNeedPushClients();
+ for (SaSsoClientModel client : needPushClients) {
pushMessage(client, message);
}
}
@@ -730,15 +705,25 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
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);
- message.set(paramName.deviceId, logoutParameter.getDeviceId());
- pushMessage(client, message);
+ pushToClientByLogoutCall(client, loginId, logoutParameter);
}
}
}
+ /**
+ * 向指定 Client 推送消息:单点注销回调
+ *
+ * @param loginId /
+ * @param logoutParameter 注销参数
+ */
+ public void pushToClientByLogoutCall(SaSsoClientModel client, Object loginId, SaLogoutParameter logoutParameter) {
+ SaSsoMessage message = new SaSsoMessage();
+ message.setType(SaSsoConsts.MESSAGE_LOGOUT_CALL);
+ message.set(paramName.loginId, loginId);
+ message.set(paramName.deviceId, logoutParameter.getDeviceId());
+ pushMessage(client, message);
+ }
+
// ------------------- Bean 获取 -------------------
@@ -776,25 +761,16 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
// ------------------- 返回相应key -------------------
/**
- * 拼接key:Ticket 查 账号Id
+ * 拼接key:TicketModel
* @param ticket ticket值
* @return key
*/
- public String splicingTicketSaveKey(String ticket) {
+ public String splicingTicketModelSaveKey(String ticket) {
return getStpLogic().getConfigOrGlobal().getTokenName() + ":ticket:" + ticket;
}
-// /**
-// * 拼接key:Ticket 查 所属的 client
-// * @param ticket ticket值
-// * @return key
-// */
-// public String splicingTicketToClientSaveKey(String ticket) {
-// return getStpLogic().getConfigOrGlobal().getTokenName() + ":ticket-client:" + ticket;
-// }
-
/**
- * 拼接key:账号Id 反查 Ticket
+ * 拼接key:Ticket 索引
*
* @param client 应用标识
* @param id 账号id
@@ -804,7 +780,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
if(SaFoxUtil.isEmpty(client) || SaSsoConsts.CLIENT_WILDCARD.equals(client)) {
client = SaSsoConsts.CLIENT_ANON;
}
- return getStpLogic().getConfigOrGlobal().getTokenName() + ":id-ticket:" + client + ":" + id;
+ return getStpLogic().getConfigOrGlobal().getTokenName() + ":ticket-index:" + client + ":" + id;
}
}
diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerUtil.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerUtil.java
new file mode 100644
index 00000000..42f15460
--- /dev/null
+++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerUtil.java
@@ -0,0 +1,300 @@
+/*
+ * 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.template;
+
+import cn.dev33.satoken.sso.config.SaSsoClientModel;
+import cn.dev33.satoken.sso.message.SaSsoMessage;
+import cn.dev33.satoken.sso.model.TicketModel;
+import cn.dev33.satoken.sso.processor.SaSsoServerProcessor;
+import cn.dev33.satoken.stp.parameter.SaLogoutParameter;
+import cn.dev33.satoken.util.SaResult;
+
+import java.util.List;
+
+/**
+ * SSO 工具类 (Server端)
+ *
+ * @author click33
+ * @since 1.43.0
+ */
+public class SaSsoServerUtil extends SaSsoTemplate {
+
+ private SaSsoServerUtil() {
+ }
+
+ /**
+ * 返回底层使用的 SaSsoServerTemplate 对象
+ * @return /
+ */
+ public static SaSsoServerTemplate getSsoTemplate() {
+ return SaSsoServerProcessor.instance.ssoServerTemplate;
+ }
+
+
+ // ---------------------- Ticket 操作 ----------------------
+
+ // 增删改
+
+ /**
+ * 删除 Ticket
+ * @param ticket Ticket码
+ */
+ public static void deleteTicket(String ticket) {
+ SaSsoServerProcessor.instance.ssoServerTemplate.deleteTicket(ticket);
+ }
+
+ /**
+ * 根据参数创建一个 ticket 码,并保存
+ *
+ * @param client 客户端标识
+ * @param loginId 账号 id
+ * @param tokenValue 会话 Token
+ * @return Ticket码
+ */
+ public static String createTicketAndSave(String client, Object loginId, String tokenValue) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.createTicketAndSave(client, loginId, tokenValue);
+ }
+
+ // 查
+
+ /**
+ * 查询 ticket ,如果 ticket 无效则返回 null
+ *
+ * @param ticket Ticket码
+ * @return 账号id
+ */
+ public static TicketModel getTicket(String ticket) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getTicket(ticket);
+ }
+
+ /**
+ * 查询 ticket 指向的 loginId,如果 ticket 码无效则返回 null
+ * @param ticket Ticket码
+ * @return 账号id
+ */
+ public static Object getLoginId(String ticket) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getLoginId(ticket);
+ }
+
+ /**
+ * 查询 ticket 指向的 loginId,并转换为指定类型
+ * @param 要转换的类型
+ * @param ticket Ticket码
+ * @param cs 要转换的类型
+ * @return 账号id
+ */
+ public static T getLoginId(String ticket, Class cs) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getLoginId(ticket, cs);
+ }
+
+ // 校验
+
+ /**
+ * 校验 Ticket,无效 ticket 会抛出异常
+ *
+ * @param ticket Ticket码
+ * @return /
+ */
+ public static TicketModel checkTicket(String ticket) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.checkTicket(ticket);
+ }
+
+ /**
+ * 校验 Ticket 码,无效 ticket 会抛出异常,如果此ticket是有效的,则立即删除
+ * @param ticket Ticket码
+ * @return 账号id
+ */
+ public static TicketModel checkTicketParamAndDelete(String ticket) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.checkTicketParamAndDelete(ticket);
+ }
+
+ /**
+ * 校验 Ticket,无效 ticket 会抛出异常,如果此ticket是有效的,则立即删除
+ *
+ * @param ticket Ticket码
+ * @param client client 标识
+ * @return /
+ */
+ public static TicketModel checkTicketParamAndDelete(String ticket, String client) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.checkTicketParamAndDelete(ticket, client);
+ }
+
+ // ticket 索引
+
+ /**
+ * 查询 指定 client、loginId 其所属的 ticket 值
+ *
+ * @param client 应用
+ * @param loginId 账号id
+ * @return Ticket值
+ */
+ public static String getTicketValue(String client, Object loginId) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getTicketValue(client, loginId);
+ }
+
+
+ // ---------------------- Client 信息获取 ----------------------
+
+ /**
+ * 获取所有 Client
+ *
+ * @return /
+ */
+ public static List getClients() {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getClients();
+ }
+
+ /**
+ * 获取应用信息,无效 client 返回 null
+ *
+ * @param client /
+ * @return /
+ */
+ public static SaSsoClientModel getClient(String client) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getClient(client);
+ }
+
+ /**
+ * 获取应用信息,无效 client 则抛出异常
+ *
+ * @param client /
+ * @return /
+ */
+ public static SaSsoClientModel getClientNotNull(String client) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getClientNotNull(client);
+ }
+
+ /**
+ * 获取匿名 client 信息
+ *
+ * @return /
+ */
+ public static SaSsoClientModel getAnonClient() {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getAnonClient();
+ }
+
+ /**
+ * 获取所有需要接收消息推送的 Client
+ *
+ * @return /
+ */
+ public static List getNeedPushClients() {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.getNeedPushClients();
+ }
+
+
+ // ------------------- 重定向 URL 构建与校验 -------------------
+
+ /**
+ * 构建 URL:sso-server 端向 sso-client 下放 ticket 的地址
+ *
+ * @param client 客户端标识
+ * @param redirect sso-client 端的重定向地址
+ * @param loginId 账号 id
+ * @param tokenValue 会话 token
+ * @return /
+ */
+ public static String buildRedirectUrl(String client, String redirect, Object loginId, String tokenValue) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.buildRedirectUrl(client, redirect, loginId, tokenValue);
+ }
+
+ /**
+ * 校验重定向 url 合法性
+ *
+ * @param client 应用标识
+ * @param url 下放ticket的url地址
+ */
+ public static void checkRedirectUrl(String client, String url) {
+ SaSsoServerProcessor.instance.ssoServerTemplate.checkRedirectUrl(client, url);
+ }
+
+
+ // ------------------- 单点注销 -------------------
+
+ /**
+ * 指定账号单点注销
+ *
+ * @param loginId 指定账号
+ */
+ public static void ssoLogout(Object loginId) {
+ SaSsoServerProcessor.instance.ssoServerTemplate.ssoLogout(loginId);
+ }
+
+ /**
+ * 指定账号单点注销
+ *
+ * @param loginId 指定账号
+ * @param logoutParameter 注销参数
+ */
+ public static void ssoLogout(Object loginId, SaLogoutParameter logoutParameter) {
+ SaSsoServerProcessor.instance.ssoServerTemplate.ssoLogout(loginId, logoutParameter);
+ }
+
+
+ // ------------------- 消息推送 -------------------
+
+ /**
+ * 向指定 Client 推送消息
+ * @param clientModel /
+ * @param message /
+ * @return /
+ */
+ public static String pushMessage(SaSsoClientModel clientModel, SaSsoMessage message) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.pushMessage(clientModel, message);
+ }
+
+ /**
+ * 向指定 client 推送消息,并将返回值转为 SaResult
+ *
+ * @param clientModel /
+ * @param message /
+ * @return /
+ */
+ public static SaResult pushMessageAsSaResult(SaSsoClientModel clientModel, SaSsoMessage message) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.pushMessageAsSaResult(clientModel, message);
+ }
+
+ /**
+ * 向指定 Client 推送消息
+ * @param client /
+ * @param message /
+ * @return /
+ */
+ public static String pushMessage(String client, SaSsoMessage message) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.pushMessage(client, message);
+ }
+
+ /**
+ * 向指定 client 推送消息,并将返回值转为 SaResult
+ *
+ * @param client /
+ * @param message /
+ * @return /
+ */
+ public static SaResult pushMessageAsSaResult(String client, SaSsoMessage message) {
+ return SaSsoServerProcessor.instance.ssoServerTemplate.pushMessageAsSaResult(client, message);
+ }
+
+ /**
+ * 向所有 Client 推送消息
+ *
+ * @param message /
+ */
+ public static void pushToAllClient(SaSsoMessage message) {
+ SaSsoServerProcessor.instance.ssoServerTemplate.pushToAllClient(message);
+ }
+
+}
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 fd597b3d..ce72fee7 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
@@ -15,19 +15,15 @@
*/
package cn.dev33.satoken.sso.template;
-import cn.dev33.satoken.SaManager;
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 模板方法类 (公共端)
+ * SSO 模板方法类 (公共端)
*
* @author click33
* @since 1.30.0
@@ -74,18 +70,11 @@ public class SaSsoTemplate {
// ----------- 消息处理
+ /**
+ * SSO 消息处理器 - 持有器
+ */
public SaSsoMessageHolder messageHolder = new SaSsoMessageHolder();
-// /**
-// * 发送 Http 请求
-// *
-// * @param url /
-// * @return /
-// */
-// public String request(String url) {
-// return SaManager.getSaHttpTemplate().get(url);
-// }
-
/**
* 处理指定消息
*
@@ -95,5 +84,4 @@ public class SaSsoTemplate {
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 f7b23bdd..cfd3b477 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
@@ -23,10 +23,13 @@ import java.util.Map;
/**
* Sa-Token-SSO 单点登录模块 工具类
+ *
+ * 请更换为 SaSsoServerUtil 或 SaSsoClientUtil
*
* @author click33
* @since 1.30.0
*/
+@Deprecated
public class SaSsoUtil {
// ---------------------- Ticket 操作 ----------------------
@@ -40,7 +43,7 @@ public class SaSsoUtil {
* @return Ticket码
*/
public static String createTicket(String client, Object loginId, String deviceId) {
- return SaSsoServerProcessor.instance.ssoServerTemplate.createTicket(client, loginId, deviceId);
+ return SaSsoServerProcessor.instance.ssoServerTemplate.createTicketAndSave(client, loginId, deviceId);
}
/**
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 b51f4f5b..e9423455 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
@@ -58,9 +58,6 @@ 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";