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

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

View File

@@ -12,20 +12,20 @@ import org.springframework.web.bind.annotation.RestController;
public class HomeController {
// 平台化首页
@RequestMapping("/home")
@RequestMapping({"/", "/home"})
public Object index() {
// 如果未登录,则先去登录
if(!StpUtil.isLogin()) {
return SaHolder.getResponse().redirect("/sso/auth");
}
// 拼接各个子系统的地址,格式形如:/sso/auth?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 link2 = "/sso/auth?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/";
// 拼接各个子系统的地址,格式形如:/sso/auth?client=xxx&redirect=${子系统首页}/sso/login?back=${子系统首页}
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?client=sso-client3&redirect=http://sa-sso-client2.com:9003/sso/login?back=http://sa-sso-client2.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 client2 = "<p><a href='" + link2 + "' target='_blank'> 进入Client2系统 </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相关请求
* http://{host}:{port}/sso/auth -- 单点登录授权地址
* http://{host}:{port}/sso/auth -- 单点登录授权地址
* http://{host}:{port}/sso/doLogin -- 账号密码登录接口接受参数name、pwd
* http://{host}:{port}/sso/signout -- 单点注销地址isSlo=true时打开
*/
@@ -42,19 +42,18 @@ public class SsoServerController {
// 配置:登录处理函数
ssoServerTemplate.strategy.doLoginHandle = (name, pwd) -> {
// 此处仅做模拟登录,真实环境应该查询数据进行登录
// 此处仅做模拟登录,真实环境应该查询数据进行登录
if("sa".equals(name) && "123456".equals(pwd)) {
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.error("登录失败!");
};
// 添加消息处理器userinfo (获取用户资料) (用于在模式三下,为 client 端开放拉取数据的接口)
// 添加消息处理器userinfo (获取用户资料) (用于为 client 端开放拉取数据的接口)
ssoServerTemplate.messageHolder.addHandle("userinfo", (ssoTemplate, message) -> {
System.out.println("收到消息:" + message);
System.out.println("loginId=" + message.get("loginId"));
// 自定义返回结果(模拟)
return SaResult.ok()

View File

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

View File

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

View File

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

View File

@@ -6,10 +6,13 @@ server:
sa-token:
# SSO-相关配置
sso-client:
# client 标识
client: sso-client1
# SSO-Server端主机地址
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:
# Redis数据库索引
database: 1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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