refactor: 调整 SSO 相关示例

This commit is contained in:
click33 2025-05-08 20:50:30 +08:00
parent 2ecd52b3be
commit 88f99c49fb
25 changed files with 117 additions and 57 deletions

View File

@ -58,8 +58,9 @@ cd sa-token-demo-sso-server & call mvn clean & cd ..
cd sa-token-demo-sso1-client & call mvn clean & cd .. cd sa-token-demo-sso1-client & call mvn clean & cd ..
cd sa-token-demo-sso2-client & call mvn clean & cd .. cd sa-token-demo-sso2-client & call mvn clean & cd ..
cd sa-token-demo-sso3-client & call mvn clean & cd .. cd sa-token-demo-sso3-client & call mvn clean & cd ..
cd sa-token-demo-sso3-client-test2 & call mvn clean & cd ..
cd sa-token-demo-sso3-client-nosdk & call mvn clean & cd .. cd sa-token-demo-sso3-client-nosdk & call mvn clean & cd ..
cd sa-token-demo-sso3-client-resdk & call mvn clean & cd ..
cd sa-token-demo-sso3-client-anon & call mvn clean & cd ..
cd .. cd ..
cd sa-token-demo-sso-for-solon cd sa-token-demo-sso-for-solon

View File

@ -41,10 +41,10 @@
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- Sa-Token 插件:整合redis (使用jackson序列化方式) --> <!-- Sa-Token 插件:整合 RedisTemplate -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId> <artifactId>sa-token-redis-template</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -58,7 +58,7 @@
<artifactId>spring-boot-starter-thymeleaf</artifactId> <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> </dependency>
<!-- Sa-Token 插件:整合 Forest 请求工具 --> <!-- Sa-Token 插件:整合 Forest 请求工具 (模式三需要通过 http 请求推送消息) -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-forest</artifactId> <artifactId>sa-token-forest</artifactId>

View File

@ -12,20 +12,20 @@ import org.springframework.web.bind.annotation.RestController;
public class HomeController { public class HomeController {
// 平台化首页 // 平台化首页
@RequestMapping("/home") @RequestMapping({"/", "/home"})
public Object index() { public Object index() {
// 如果未登录则先去登录 // 如果未登录则先去登录
if(!StpUtil.isLogin()) { if(!StpUtil.isLogin()) {
return SaHolder.getResponse().redirect("/sso/auth"); return SaHolder.getResponse().redirect("/sso/auth");
} }
// 拼接各个子系统的地址格式形如/sso/auth?redirect=${子系统首页}/sso/login?back=${子系统首页} // 拼接各个子系统的地址格式形如/sso/auth?client=xxx&redirect=${子系统首页}/sso/login?back=${子系统首页}
String link1 = "/sso/auth?redirect=http://sa-sso-client1.com:9003/sso/login?back=http://sa-sso-client1.com:9003/"; String link1 = "/sso/auth?client=sso-client3&redirect=http://sa-sso-client1.com:9003/sso/login?back=http://sa-sso-client1.com:9003/";
String link2 = "/sso/auth?redirect=http://sa-sso-client2.com:9003/sso/login?back=http://sa-sso-client2.com:9003/"; String link2 = "/sso/auth?client=sso-client3&redirect=http://sa-sso-client2.com:9003/sso/login?back=http://sa-sso-client2.com:9003/";
String link3 = "/sso/auth?redirect=http://sa-sso-client3.com:9003/sso/login?back=http://sa-sso-client3.com:9003/"; String link3 = "/sso/auth?client=sso-client3&redirect=http://sa-sso-client3.com:9003/sso/login?back=http://sa-sso-client3.com:9003/";
// 组织网页结构返回到前端 // 组织网页结构返回到前端
String title = "<h2>SSO 平台首页</h2>"; String title = "<h2>SSO 平台首页 (平台中心模式)</h2>";
String client1 = "<p><a href='" + link1 + "' target='_blank'> 进入Client1系统 </a></p>"; String client1 = "<p><a href='" + link1 + "' target='_blank'> 进入Client1系统 </a></p>";
String client2 = "<p><a href='" + link2 + "' target='_blank'> 进入Client2系统 </a></p>"; String client2 = "<p><a href='" + link2 + "' target='_blank'> 进入Client2系统 </a></p>";
String client3 = "<p><a href='" + link3 + "' target='_blank'> 进入Client3系统 </a></p>"; String client3 = "<p><a href='" + link3 + "' target='_blank'> 进入Client3系统 </a></p>";

View File

@ -22,7 +22,7 @@ public class SsoServerController {
/** /**
* SSO-Server端处理所有SSO相关请求 * SSO-Server端处理所有SSO相关请求
* http://{host}:{port}/sso/auth -- 单点登录授权地址 * http://{host}:{port}/sso/auth -- 单点登录授权地址
* http://{host}:{port}/sso/doLogin -- 账号密码登录接口接受参数namepwd * http://{host}:{port}/sso/doLogin -- 账号密码登录接口接受参数namepwd
* http://{host}:{port}/sso/signout -- 单点注销地址isSlo=true时打开 * http://{host}:{port}/sso/signout -- 单点注销地址isSlo=true时打开
*/ */
@ -42,19 +42,18 @@ public class SsoServerController {
// 配置登录处理函数 // 配置登录处理函数
ssoServerTemplate.strategy.doLoginHandle = (name, pwd) -> { ssoServerTemplate.strategy.doLoginHandle = (name, pwd) -> {
// 此处仅做模拟登录真实环境应该查询数据进行登录 // 此处仅做模拟登录真实环境应该查询数据进行登录
if("sa".equals(name) && "123456".equals(pwd)) { if("sa".equals(name) && "123456".equals(pwd)) {
String deviceId = SaHolder.getRequest().getParam("deviceId", SaFoxUtil.getRandomString(32)); String deviceId = SaHolder.getRequest().getParam("deviceId", SaFoxUtil.getRandomString(32));
StpUtil.login(10001, SaLoginParameter.create().setDeviceId(deviceId)); StpUtil.login(10001, new SaLoginParameter().setDeviceId(deviceId));
return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue()); return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
} }
return SaResult.error("登录失败!"); return SaResult.error("登录失败!");
}; };
// 添加消息处理器userinfo (获取用户资料) 用于在模式三下 client 端开放拉取数据的接口 // 添加消息处理器userinfo (获取用户资料) 用于 client 端开放拉取数据的接口
ssoServerTemplate.messageHolder.addHandle("userinfo", (ssoTemplate, message) -> { ssoServerTemplate.messageHolder.addHandle("userinfo", (ssoTemplate, message) -> {
System.out.println("收到消息:" + message); System.out.println("收到消息:" + message);
System.out.println("loginId=" + message.get("loginId"));
// 自定义返回结果模拟 // 自定义返回结果模拟
return SaResult.ok() return SaResult.ok()

View File

@ -7,7 +7,7 @@ sa-token:
# 打印操作日志 # 打印操作日志
is-log: true is-log: true
# ------- SSO 模式一配置 (非模式一不需要配置) # SSO 模式一配置 (非模式一不需要配置)
# cookie: # cookie:
# # 配置 Cookie 作用域 # # 配置 Cookie 作用域
# domain: stp.com # domain: stp.com
@ -16,7 +16,7 @@ sa-token:
sso-server: sso-server:
# Ticket有效期 (单位: 秒),默认五分钟 # Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300 ticket-timeout: 300
# 主页路由,在不指定 redirect 参数时,默认跳转的地址 # 主页路由:在 /sso/auth 登录页不指定 redirect 参数时,默认跳转的地址
home-route: /home home-route: /home
# 是否启用匿名 client (开启匿名 client 后,允许客户端接入时不提交 client 参数) # 是否启用匿名 client (开启匿名 client 后,允许客户端接入时不提交 client 参数)
allow-anon-client: true allow-anon-client: true
@ -26,6 +26,10 @@ sa-token:
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# 应用列表:配置接入的应用信息 # 应用列表:配置接入的应用信息
clients: clients:
# 应用 sso-client1采用模式一对接 (同域、同Redis)
sso-client1:
client: sso-client1
allow-url: "*"
# 应用 sso-client2采用模式二对接 (跨域、同Redis) # 应用 sso-client2采用模式二对接 (跨域、同Redis)
sso-client2: sso-client2:
client: sso-client2 client: sso-client2

View File

@ -34,21 +34,19 @@
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- Sa-Token 插件:整合SSO --> <!-- Sa-Token 插件:整合 SSO -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId> <artifactId>sa-token-sso</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- Sa-Token 整合redis (使用jackson序列化方式) --> <!-- Sa-Token 整合 RedisTemplate -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId> <artifactId>sa-token-redis-template</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- 提供Redis连接池 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>

View File

@ -1,12 +1,17 @@
package com.pj.sso; package com.pj.sso;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.sso.SaSsoManager; import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult; import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/** /**
* Sa-Token-SSO Client端 Controller * Sa-Token-SSO Client端 Controller
* @author click33 * @author click33
@ -16,13 +21,17 @@ public class SsoClientController {
// SSO-Client端首页 // SSO-Client端首页
@RequestMapping("/") @RequestMapping("/")
public String index() { public String index(HttpServletRequest request) {
String authUrl = SaSsoManager.getClientConfig().splicingAuthUrl(); String url = SaFoxUtil.encodeUrl( SaFoxUtil.joinParam(SaHolder.getRequest().getUrl(), request.getQueryString()) );
String signoutUrl = SaSsoManager.getClientConfig().splicingSignoutUrl(); SaSsoClientConfig cfg = SaSsoManager.getClientConfig();
String str = "<h2>Sa-Token SSO-Client 应用端 (模式一)</h2>" + String str = "<h2>Sa-Token SSO-Client 应用端 (模式一)</h2>" +
"<p>当前会话是否登录:" + StpUtil.isLogin() + " (" + StpUtil.getLoginId("") + ")</p>" + "<p>当前会话是否登录:" + StpUtil.isLogin() + " (" + StpUtil.getLoginId("") + ")</p>" +
"<p><a href=\"javascript:location.href='" + authUrl + "?mode=simple&redirect=' + encodeURIComponent(location.href);\">登录</a> " + "<p>" +
"<a href=\"javascript:location.href='" + signoutUrl + "?back=' + encodeURIComponent(location.href);\">注销</a> </p>"; "<a href='" + cfg.splicingAuthUrl() + "?mode=simple&client=" + cfg.getClient() + "&redirect=" + url + "'>登录</a> - " +
"<a href='" + cfg.splicingSignoutUrl() + "?singleDeviceIdLogout=true&back=" + url + "'>单浏览器注销</a> - " +
"<a href='" + cfg.splicingSignoutUrl() + "?back=" + url + "'>全端注销</a> " +
"</p>";
return str; return str;
} }

View File

@ -6,10 +6,13 @@ server:
sa-token: sa-token:
# SSO-相关配置 # SSO-相关配置
sso-client: sso-client:
# client 标识
client: sso-client1
# SSO-Server端主机地址 # SSO-Server端主机地址
server-url: http://sso.stp.com:9000 server-url: http://sso.stp.com:9000
# 配置 Sa-Token 单独使用的Redis连接 (需要引入 sa-token-alone-redis 依赖) (此处需要和 SSO-Server 端连接同一个Redis # 配置 Sa-Token 单独使用的Redis连接此处需要和 SSO-Server 端连接同一个 Redis
# 注:使用 alone-redis 需要在 pom.xml 引入 sa-token-alone-redis 依赖
alone-redis: alone-redis:
# Redis数据库索引 # Redis数据库索引
database: 1 database: 1

View File

@ -41,10 +41,10 @@
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- Sa-Token 整合redis (使用jackson序列化方式) --> <!-- Sa-Token 整合 RedisTemplate -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId> <artifactId>sa-token-redis-template</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>

View File

@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class H5Controller { public class H5Controller {
// 当前是否登录 // 判断当前是否登录
@RequestMapping("/sso/isLogin") @RequestMapping("/sso/isLogin")
public Object isLogin() { public Object isLogin() {
return SaResult.data(StpUtil.isLogin()).set("loginId", StpUtil.getLoginIdDefaultNull()); return SaResult.data(StpUtil.isLogin()).set("loginId", StpUtil.getLoginIdDefaultNull());
@ -31,7 +31,7 @@ public class H5Controller {
return SaResult.data(serverAuthUrl); return SaResult.data(serverAuthUrl);
} }
// 根据ticket进行登录 // 根据 ticket 进行登录
@RequestMapping("/sso/doLoginByTicket") @RequestMapping("/sso/doLoginByTicket")
public SaResult doLoginByTicket(String ticket) { public SaResult doLoginByTicket(String ticket) {
SaCheckTicketResult ctr = SaSsoClientProcessor.instance.checkTicket(ticket); SaCheckTicketResult ctr = SaSsoClientProcessor.instance.checkTicket(ticket);

View File

@ -4,6 +4,9 @@ server:
# sa-token配置 # sa-token配置
sa-token: sa-token:
# 打印操作日志
is-log: true
# SSO-相关配置 # SSO-相关配置
sso-client: sso-client:
# 应用标识 # 应用标识
@ -17,7 +20,7 @@ sa-token:
# 配置 Sa-Token 单独使用的Redis连接此处需要和 SSO-Server 端连接同一个 Redis # 配置 Sa-Token 单独使用的Redis连接此处需要和 SSO-Server 端连接同一个 Redis
# 注:使用 alone-redis 需要在 pom.xml 引入 sa-token-alone-redis 依赖 # 注:使用 alone-redis 需要在 pom.xml 引入 sa-token-alone-redis 依赖
alone-redis: alone-redis:
# Redis数据库索引 # Redis数据库索引
database: 1 database: 1
# Redis服务器地址 # Redis服务器地址

View File

@ -40,13 +40,13 @@
<artifactId>sa-token-sso</artifactId> <artifactId>sa-token-sso</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- Sa-Token 整合redis (使用jackson序列化方式) --> <!-- Sa-Token 整合 RedisTemplate -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId> <artifactId>sa-token-redis-template</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- 提供Redis连接池 --> <!-- 提供Redis连接池 -->
<dependency> <dependency>

View File

@ -47,6 +47,8 @@ public class SsoClientController {
// 配置SSO相关参数 // 配置SSO相关参数
@Autowired @Autowired
private void configSso(SaSsoClientTemplate ssoClientTemplate) { private void configSso(SaSsoClientTemplate ssoClientTemplate) {
// 重写 loginId centerId 转换策略函数做到本地应用 userId 与认证中心 userId 的互相映射
// // centerId 转换为 loginId 的函数 // // centerId 转换为 loginId 的函数
// ssoClientTemplate.strategy.convertCenterIdToLoginId = (centerId) -> { // ssoClientTemplate.strategy.convertCenterIdToLoginId = (centerId) -> {
// return "Stu" + centerId; // return "Stu" + centerId;
@ -72,7 +74,10 @@ public class SsoClientController {
return "尚未登录,无法获取"; return "尚未登录,无法获取";
} }
// 获取本地 loginId 对应的认证中心 centerId // 原写法直接调用 StpUtil.getLoginId() 当做 centerId 来提交
// Object centerId = StpUtil.getLoginId();
// 新写法获取本地 loginId 对应的认证中心 centerId
Object centerId = SaSsoClientUtil.getSsoTemplate().strategy.convertLoginIdToCenterId.run(StpUtil.getLoginId()); Object centerId = SaSsoClientUtil.getSsoTemplate().strategy.convertLoginIdToCenterId.run(StpUtil.getLoginId());
// 推送消息 // 推送消息

View File

@ -21,7 +21,7 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- Http 请求工具 --> <!-- Http 请求工具 -->
<dependency> <dependency>
<groupId>com.dtflys.forest</groupId> <groupId>com.dtflys.forest</groupId>

View File

@ -41,10 +41,10 @@
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>
<!-- Sa-Token 整合redis (使用jackson序列化方式) --> <!-- Sa-Token 整合 RedisTemplate -->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId> <artifactId>sa-token-redis-template</artifactId>
<version>${sa-token.version}</version> <version>${sa-token.version}</version>
</dependency> </dependency>

View File

@ -48,7 +48,7 @@ public class SaSsoServerConfig implements Serializable {
public long ticketTimeout = 60 * 5; public long ticketTimeout = 60 * 5;
/** /**
* 主页路由 /sso/auth 登录后不指定 redirect 参数的情况下默认跳转的路由 * 主页路由 /sso/auth 登录页不指定 redirect 参数时默认跳转的地址
*/ */
public String homeRoute; public String homeRoute;
@ -176,14 +176,14 @@ public class SaSsoServerConfig implements Serializable {
} }
/** /**
* @return 主页路由 /sso/auth 登录后不指定 redirect 参数的情况下默认跳转的路由 * @return 主页路由 /sso/auth 登录页不指定 redirect 参数时默认跳转的地址
*/ */
public String getHomeRoute() { public String getHomeRoute() {
return homeRoute; return homeRoute;
} }
/** /**
* @param homeRoute 主页路由 /sso/auth 登录后不指定 redirect 参数的情况下默认跳转的路由 * @param homeRoute 主页路由 /sso/auth 登录页不指定 redirect 参数时默认跳转的地址
* @return 对象自身 * @return 对象自身
*/ */
public SaSsoServerConfig setHomeRoute(String homeRoute) { public SaSsoServerConfig setHomeRoute(String homeRoute) {

View File

@ -41,7 +41,7 @@ public class SaSsoMessage extends LinkedHashMap<String, Object> implements SaSet
/** /**
* KEYTYPE * KEYTYPE
*/ */
public static final String MSG_TYPE = "msg_type"; public static final String MSG_TYPE = "msgType";
public SaSsoMessage() { public SaSsoMessage() {

View File

@ -275,7 +275,7 @@ public class SaSsoClientProcessor {
logoutParameter.setDeviceId(stpLogic.getLoginDeviceId()); logoutParameter.setDeviceId(stpLogic.getLoginDeviceId());
} }
Object centerId = ssoClientTemplate.strategy.convertLoginIdToCenterId.run(stpLogic.getLoginId()); Object centerId = ssoClientTemplate.strategy.convertLoginIdToCenterId.run(stpLogic.getLoginId());
SaSsoMessage message = ssoClientTemplate.buildSloMessage(centerId, logoutParameter); SaSsoMessage message = ssoClientTemplate.buildSignoutMessage(centerId, logoutParameter);
SaResult result = ssoClientTemplate.pushMessageAsSaResult(message); SaResult result = ssoClientTemplate.pushMessageAsSaResult(message);
// 如果 sso-server 响应的状态码非200代表业务失败将回应的 msg 字段作为异常抛出 // 如果 sso-server 响应的状态码非200代表业务失败将回应的 msg 字段作为异常抛出

View File

@ -85,7 +85,7 @@ public class SaSsoServerProcessor {
// sso-server接收推送消息 // sso-server接收推送消息
if(req.isPath(apiName.ssoPushS)) { if(req.isPath(apiName.ssoPushS)) {
return ssoPush(); return ssoPushS();
} }
// 默认返回 // 默认返回
@ -199,7 +199,7 @@ public class SaSsoServerProcessor {
* *
* @return 处理结果 * @return 处理结果
*/ */
public Object ssoPush() { public Object ssoPushS() {
ParamName paramName = ssoServerTemplate.paramName; ParamName paramName = ssoServerTemplate.paramName;
SaSsoServerConfig ssoServerConfig = ssoServerTemplate.getServerConfig(); SaSsoServerConfig ssoServerConfig = ssoServerTemplate.getServerConfig();

View File

@ -212,7 +212,7 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
* @param logoutParameter 单点注销 * @param logoutParameter 单点注销
* @return 单点注销URL * @return 单点注销URL
*/ */
public SaSsoMessage buildSloMessage(Object loginId, SaLogoutParameter logoutParameter) { public SaSsoMessage buildSignoutMessage(Object loginId, SaLogoutParameter logoutParameter) {
SaSsoMessage message = new SaSsoMessage(); SaSsoMessage message = new SaSsoMessage();
message.setType(SaSsoConsts.MESSAGE_SIGNOUT); message.setType(SaSsoConsts.MESSAGE_SIGNOUT);
message.set(paramName.client, getClient()); message.set(paramName.client, getClient());

View File

@ -28,7 +28,7 @@ import java.util.Map;
* @author click33 * @author click33
* @since 1.38.0 * @since 1.38.0
*/ */
public class SaSsoClientUtil extends SaSsoTemplate { public class SaSsoClientUtil {
private SaSsoClientUtil() { private SaSsoClientUtil() {
} }
@ -120,8 +120,8 @@ public class SaSsoClientUtil extends SaSsoTemplate {
* @param logoutParameter 单点注销 * @param logoutParameter 单点注销
* @return 单点注销URL * @return 单点注销URL
*/ */
public static SaSsoMessage buildSloMessage(Object loginId, SaLogoutParameter logoutParameter) { public static SaSsoMessage buildSignoutMessage(Object loginId, SaLogoutParameter logoutParameter) {
return SaSsoClientProcessor.instance.ssoClientTemplate.buildSloMessage(loginId, logoutParameter); return SaSsoClientProcessor.instance.ssoClientTemplate.buildSignoutMessage(loginId, logoutParameter);
} }
} }

View File

@ -292,7 +292,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
*/ */
public SaSsoClientModel getClientNotNull(String client) { public SaSsoClientModel getClientNotNull(String client) {
if(SaFoxUtil.isEmpty(client)) { if(SaFoxUtil.isEmpty(client)) {
if(getServerConfig().getAllowAnonClient()) { if(getConfigOfAllowAnonClient()) {
return getAnonClient(); return getAnonClient();
} else { } else {
throw new SaSsoException("client 标识不可为空"); throw new SaSsoException("client 标识不可为空");
@ -307,7 +307,16 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
} }
/** /**
* 获取匿名 client 信息 * 获取配置项是否允许匿名 client 接入
*
* @return /
*/
public boolean getConfigOfAllowAnonClient() {
return getServerConfig().getAllowAnonClient();
}
/**
* 获取匿名 client 配置信息
* *
* @return / * @return /
*/ */
@ -697,8 +706,22 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
* @param message / * @param message /
*/ */
public void pushToAllClient(SaSsoMessage message) { public void pushToAllClient(SaSsoMessage message) {
pushToAllClient(message, null);
}
/**
* 向所有 Client 推送消息并忽略掉某个 client
*
* @param ignoreClient 要被忽略掉的 client null 代表不忽略
* @param message /
*/
public void pushToAllClient(SaSsoMessage message, String ignoreClient) {
// TODO 待验证
List<SaSsoClientModel> needPushClients = getNeedPushClients(); List<SaSsoClientModel> needPushClients = getNeedPushClients();
for (SaSsoClientModel client : needPushClients) { for (SaSsoClientModel client : needPushClients) {
if(ignoreClient != null && ignoreClient.equals(client.getClient())) {
continue;
}
strategy.asyncRun.run(() -> pushMessage(client, message)); strategy.asyncRun.run(() -> pushMessage(client, message));
} }
} }

View File

@ -30,7 +30,7 @@ import java.util.List;
* @author click33 * @author click33
* @since 1.43.0 * @since 1.43.0
*/ */
public class SaSsoServerUtil extends SaSsoTemplate { public class SaSsoServerUtil {
private SaSsoServerUtil() { private SaSsoServerUtil() {
} }
@ -297,4 +297,14 @@ public class SaSsoServerUtil extends SaSsoTemplate {
SaSsoServerProcessor.instance.ssoServerTemplate.pushToAllClient(message); SaSsoServerProcessor.instance.ssoServerTemplate.pushToAllClient(message);
} }
/**
* 向所有 Client 推送消息并忽略掉某个 client
*
* @param ignoreClient 要被忽略掉的 client null 代表不忽略
* @param message /
*/
public static void pushToAllClient(SaSsoMessage message, String ignoreClient) {
SaSsoServerProcessor.instance.ssoServerTemplate.pushToAllClient(message, ignoreClient);
}
} }

View File

@ -71,6 +71,7 @@ public class SaSsoBeanRegister {
* @return / * @return /
*/ */
@Bean @Bean
@Condition(onMissingBean = SaSsoServerTemplate.class)
public SaSsoServerTemplate getSaSsoServerTemplate() { public SaSsoServerTemplate getSaSsoServerTemplate() {
return SaSsoServerProcessor.instance.ssoServerTemplate; return SaSsoServerProcessor.instance.ssoServerTemplate;
} }
@ -81,6 +82,7 @@ public class SaSsoBeanRegister {
* @return / * @return /
*/ */
@Bean @Bean
@Condition(onMissingBean = SaSsoClientTemplate.class)
public SaSsoClientTemplate getSaSsoClientTemplate() { public SaSsoClientTemplate getSaSsoClientTemplate() {
return SaSsoClientProcessor.instance.ssoClientTemplate; return SaSsoClientProcessor.instance.ssoClientTemplate;
} }

View File

@ -23,6 +23,7 @@ import cn.dev33.satoken.sso.processor.SaSsoServerProcessor;
import cn.dev33.satoken.sso.template.SaSsoClientTemplate; import cn.dev33.satoken.sso.template.SaSsoClientTemplate;
import cn.dev33.satoken.sso.template.SaSsoServerTemplate; import cn.dev33.satoken.sso.template.SaSsoServerTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -61,6 +62,7 @@ public class SaSsoBeanRegister {
* @return / * @return /
*/ */
@Bean @Bean
@ConditionalOnMissingBean(SaSsoServerTemplate.class)
public SaSsoServerTemplate getSaSsoServerTemplate() { public SaSsoServerTemplate getSaSsoServerTemplate() {
return SaSsoServerProcessor.instance.ssoServerTemplate; return SaSsoServerProcessor.instance.ssoServerTemplate;
} }
@ -71,6 +73,7 @@ public class SaSsoBeanRegister {
* @return / * @return /
*/ */
@Bean @Bean
@ConditionalOnMissingBean(SaSsoClientTemplate.class)
public SaSsoClientTemplate getSaSsoClientTemplate() { public SaSsoClientTemplate getSaSsoClientTemplate() {
return SaSsoClientProcessor.instance.ssoClientTemplate; return SaSsoClientProcessor.instance.ssoClientTemplate;
} }