Sa-TokenSa-Token
主题
首页文档博客
视频
乐之者java(登录认证/权限管理/apiKey等)抓蛙师(23集)朱老师的小课堂(7集)王清江唷 SSO篇(29集)fox说技术(7集)架构驿站(11集)王清江唷(99集)筑梦信仰-joy(20集)达达-Java(26集)晒太阳的盐(22集)[ + 课程提交 ]
案例
Gitee - Awesome-Sa-TokenGitHub - Awesome-Sa-TokenAtomGit - Awesome-Sa-Token
加群需求提交赞助🔥 SSO/OAuth2 商业版
安全推荐
开发者安全 ChecklistAPI 安全 Checklist腾讯代码安全指南Web 安全学习笔记OWASP Cheat Sheet SeriesPayloadsAllTheThings
相关资源
更新日志常见报错推荐公众号在线考试在线提问问卷调查
  • 开始

    • 框架介绍
    • 在 SpringBoot 环境集成
    • 在 WebFlux 环境集成
    • 在 Solon 环境集成
    • 其它环境集成示例
    • 源码运行指南
    • Sa-Token 集成示例大全下载
  • 基础

    • 登录认证
    • 权限认证
    • 踢人下线
    • 注解鉴权
    • 路由拦截鉴权
    • Session会话
    • 框架配置
  • 深入

    • 集成 Redis
    • 前后端分离
    • 自定义 Token 风格
    • Token 提交前缀
    • 同端互斥登录
    • 记住我模式
    • 登录参数 & 注销参数
    • 二级认证
    • 模拟他人 & 身份切换
    • 账号封禁
    • 密码加密
    • 会话查询
    • Http Basic/Digest 认证
    • 全局侦听器
    • 全局过滤器
    • 多账号认证
  • 单点登录

    • 单点登录简述
    • 搭建统一认证中心:SSO-Server
    • SSO-Server 认证中心开放 API 接口
    • SSO模式一 共享Cookie同步会话
    • SSO模式二 URL重定向传播会话
    • SSO模式三 Http请求获取会话
    • 配置域名校验
    • 定制化登录页面
    • 自定义API路由
    • 平台中心跳转模式
    • 匿名 client 接入
    • 单点注销
    • 前后端分离下的整合方案
    • 消息推送机制
    • 用户数据同步 / 迁移
    • NoSdk、ReSdk 模式与非 java 项目
    • SSO 代码 API 参考
    • 常见问题总结
    • Sa-Pro:单点登录商业版
  • OAuth2.0

    • OAuth2.0简述
    • OAuth2-Server搭建
    • OAuth2-Server端开放 API 接口
    • 自定义数据加载器
    • 配置 client 域名校验
    • 自定义 Scope 权限及处理器
    • 为 Scope 划分等级
    • 自定义 grant_type
    • 定制化登录页面与授权页面
    • 自定义 API 路由
    • OAuth2-Server端前后台分离
    • OpenId 与 UnionId
    • 开启 OIDC 协议
    • 使用注解校验 Access-Token
    • OAuth2-与登录会话实现数据互通
    • OAuth2 代码 API 参考
    • 常见问题总结
    • Sa-Max:统一认证商业版
  • 微服务

    • 分布式Session会话
    • 网关统一鉴权
    • 内部服务外网隔离
    • 依赖引入说明
  • 插件

    • AOP注解鉴权
    • 临时 Token 认证
    • Quick-Login快速登录插件
    • Alone独立Redis插件
    • Alone独立Redisson插件
    • 缓存层扩展
    • JSON 序列化扩展
    • 序列化插件扩展包
    • HTTP 请求扩展
    • 和 Thymeleaf 集成
    • 和 Freemarker 集成
    • 注解鉴权 SpEL 表达式
    • 和 jwt 集成
    • 和 Dubbo 集成
    • 和 gRPC 集成
    • API 接口参数签名
    • API Key 接口调用秘钥
    • Sa-Token 插件开发指南
    • 自定义 SaTokenContext 指南
  • API手册

    • StpUtil-鉴权工具类
    • SaSession-会话对象
    • SaTokenDao-数据持久接口
    • SaStrategy-全局策略
    • 全局类、方法
  • 框架设计

    • 仓库目录
    • 数据结构
  • 其它

    • 更新日志
    • 框架生态
    • 框架博客
    • 推荐公众号
    • 加入讨论群
    • Sa-Token 内容合作群
    • 赞助 Sa-Token
    • 需求提交
    • 问卷调查
  • 附录

    • 常见问题排查
    • 框架名词解释
    • Sa-Token功能结构图
    • 全局 Log 输出
    • 异步 & Mock 上下文
    • 未登录场景值详解
    • Token有效期详解
    • Session模型详解
    • 数据读写三大作用域
    • TokenInfo参数详解
    • 异常细分状态码
    • 自定义注解
    • 防火墙
    • 参考:把权限放在缓存里
    • 参考:把路由拦截鉴权动态化
    • 解决反向代理 uri 丢失的问题
    • 解决跨域问题
    • 技术选型:SSO 与 OAuth2 对比
    • 集成 MongoDB 参考一
    • 集成 MongoDB 参考二
    • 从 Shiro、SpringSecurity、JWT 迁移
    • issue 提问模板
    • 为Sa-Token贡献代码
    • Sa-Token开源大事记
    • 团队成员
    • Sa-Token框架掌握度--在线考试







----- 到底线了 -----

×

一个项目搞定:同域、跨域、共享Redis、跨Redis、前后端一体、前后端分离、纯 js、vue2、vue3、非 Sa-Token 项目、非 java 项目等架构下的 SSO 认证需求。

一次购买,永久授权。全源码交付,不含密 Jar。提供售后技术支持。

SSO模式二 URL重定向传播会话 ​

如果我们的多个系统:部署在不同的域名之下,但是后端可以连接同一个Redis,那么便可以使用 [URL重定向传播会话] 的方式做到单点登录。

1、设计思路 ​

首先我们再次复习一下,多个系统之间为什么无法同步登录状态?

  1. 前端的Token无法在多个系统下共享。
  2. 后端的Session无法在多个系统间共享。

关于第二点,我们已在 "SSO模式一" 章节中阐述,使用 Alone独立Redis插件 做到权限缓存直连 SSO-Redis 数据中心,在此不再赘述。

而第一点,才是我们解决问题的关键所在,在跨域模式下,意味着 "共享Cookie方案" 的失效,我们必须采用一种新的方案来传递Token。

  1. 用户在 子系统 点击 [登录] 按钮。
  2. 用户跳转到子系统登录接口 /sso/login,并携带 back参数 记录初始页面URL。
    • 形如:http://{sso-client}/sso/login?back=xxx
  3. 子系统检测到此用户尚未登录,再次将其重定向至SSO认证中心,并携带redirect参数记录子系统的登录页URL。
    • 形如:http://{sso-server}/sso/auth?redirect=xxx?back=xxx
  4. 用户进入了 SSO认证中心 的登录页面,开始登录。
  5. 用户 输入账号密码 并 登录成功,SSO认证中心再次将用户重定向至子系统的登录接口/sso/login,并携带ticket码参数。
    • 形如:http://{sso-client}/sso/login?back=xxx&ticket=xxxxxxxxx
  6. 子系统根据 ticket码 从 SSO-Redis 中获取账号id,并在子系统登录此账号会话。
  7. 子系统将用户再次重定向至最初始的 back 页面。

整个过程,除了第四步用户在SSO认证中心登录时会被打断,其余过程均是自动化的,当用户在另一个子系统再次点击[登录]按钮,由于此用户在SSO认证中心已有会话存在, 所以第四步也将自动化,也就是单点登录的最终目的 —— 一次登录,处处通行。

下面我们按照步骤依次完成上述过程:

2、准备工作 ​

首先修改hosts文件(C:\windows\system32\drivers\etc\hosts),添加以下IP映射,方便我们进行测试:

url
127.0.0.1 sa-sso-server.com
127.0.0.1 sa-sso-client1.com
127.0.0.1 sa-sso-client2.com
127.0.0.1 sa-sso-client3.com
1
2
3
4

更改了 hosts 但无法访问?

  • 可能 1:你没保存。
  • 可能 2:你后端项目没启动。
  • 可能 3:你访问时端口写错了。
  • 可能 4:你开了 VPN,关掉试试。

3、搭建 Client 端项目 ​

demo

搭建示例在官方仓库的 /sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/,如遇到难点可结合源码进行测试学习。Sa-Token 集成示例大全下载 。

3.1、去除 SSO-Server 的 Cookie 作用域配置 ​

在SSO模式一章节中我们打开了配置:

yaml
sa-token: 
    cookie: 
        # 配置 Cookie 作用域 
        domain: stp.com
1
2
3
4

此为模式一专属配置,现在我们将其注释掉(一定要注释掉!)

3.2、创建 SSO-Client 端项目 ​

创建一个 SpringBoot 项目 sa-token-demo-sso2-client,引入依赖:

xml
<!-- Sa-Token 权限认证, 在线文档:https://sa-token.com -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-spring-boot-starter</artifactId>
	<version>1.46.0</version>
</dependency>
<!-- Sa-Token 插件:整合SSO -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-sso</artifactId>
	<version>1.46.0</version>
</dependency>

<!-- Sa-Token 整合 RedisTemplate -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-redis-template</artifactId>
	<version>1.46.0</version>
</dependency>
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
</dependency>

<!-- Sa-Token插件:权限缓存与业务缓存分离 -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-alone-redis</artifactId>
	<version>1.46.0</version>
</dependency>

<!-- Sa-Token 插件:整合 Forest 请求工具 -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-forest</artifactId>
	<version>1.46.0</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

也可选用 sa-token-rest-template(Spring Boot 2/3/4)或 sa-token-rest-client(Spring Boot 3.2+)作为 HTTP 请求处理器,详见:HTTP 请求扩展。

3.3、创建 SSO-Client 端认证接口 ​

同 SSO-Server 一样,Sa-Token 为 SSO-Client 端所需代码也提供了完整的封装,你只需提供一个访问入口,接入 Sa-Token 的方法即可。

java

/**
 * Sa-Token-SSO Client端 Controller 
 */
@RestController
public class SsoClientController {

	// 首页 
	@RequestMapping("/")
	public String index() {
		String str = "<h2>Sa-Token SSO-Client 应用端 (模式二)</h2>" +
					"<p>当前会话是否登录:" + StpUtil.isLogin() + " (" + StpUtil.getLoginId("") + ")</p>" +
					"<p> " +
						"<a href='/sso/login?back=/'>登录</a> - " +
						"<a href='/sso/logoutByAlone?back=/'>单应用注销</a> - " +
						"<a href='/sso/logout?back=self'>全端注销</a> - " +
						"<a href='/sso/myInfo' target='_blank'>账号资料</a>" +
					"</p>";
		return str;
	}
	
	/*
	 * SSO-Client端:处理所有SSO相关请求 
	 * 		http://{host}:{port}/sso/login			-- Client 端登录地址
	 * 		http://{host}:{port}/sso/logout			-- Client 端注销地址(isSlo=true时打开)
	 * 		http://{host}:{port}/sso/pushC			-- Client 端接收消息推送地址
	 */
	@RequestMapping("/sso/*")
	public Object ssoRequest() {
		return SaSsoClientProcessor.instance.dister();
	}

	// 配置SSO相关参数
	@Autowired
	private void configSso(SaSsoClientTemplate ssoClientTemplate) {

	}

	// 当前应用独自注销 (不退出其它应用)
	@RequestMapping("/sso/logoutByAlone")
	public Object logoutByAlone() {
		StpUtil.logout();
		return SaSsoClientProcessor.instance._ssoLogoutBack(SaHolder.getRequest(), SaHolder.getResponse());
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

全局异常处理:

java
@RestControllerAdvice
public class GlobalExceptionHandler {
	// 全局异常拦截 
	@ExceptionHandler
	public SaResult handlerException(Exception e) {
		e.printStackTrace(); 
		return SaResult.error(e.getMessage());
	}
}
1
2
3
4
5
6
7
8
9
3.4、配置SSO认证中心地址 ​

你需要在 application.yml 配置如下信息:

yaml
# 端口
server:
    port: 9002

# sa-token配置 
sa-token: 
    # 打印操作日志
    is-log: true
    # SSO-相关配置
    sso-client: 
        # 应用标识
        client: sso-client2
        # SSO-Server 端主机地址
        server-url: http://sa-sso-server.com:9000
        # API 接口调用秘钥 (单点注销时会用到)
        secret-key: SSO-C2-kQwIOrYvnXmSDkwEiFngrKidMcdrgKor

    # 配置 Sa-Token 单独使用的Redis连接(此处需要和 SSO-Server 端连接同一个 Redis)
    # 注:使用 alone-redis 需要在 pom.xml 引入 sa-token-alone-redis 依赖
    alone-redis: 
        # Redis数据库索引 (默认为0)
        database: 1
        # Redis服务器地址
        host: 127.0.0.1
        # Redis服务器连接端口
        port: 6379
        # Redis服务器连接密码(默认为空)
        password: 
        # 连接超时时间
        timeout: 10s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

注意点:sa-token.alone-redis 的配置需要和SSO-Server端连接同一个Redis(database 值也要一样!database 值也要一样!database 值也要一样!重说三!)

3.5、写启动类 ​

java
@SpringBootApplication
public class SaSso2ClientApplication {
	public static void main(String[] args) {
		SpringApplication.run(SaSso2ClientApplication.class, args);
		
		System.out.println();
		System.out.println("---------------------- Sa-Token SSO 模式二 Client 端启动成功 ----------------------");
		System.out.println("配置信息:" + SaSsoManager.getClientConfig());
		System.out.println("测试访问应用端一: http://sa-sso-client1.com:9002");
		System.out.println("测试访问应用端二: http://sa-sso-client2.com:9002");
		System.out.println("测试访问应用端三: http://sa-sso-client3.com:9002");
		System.out.println("测试前需要根据官网文档修改hosts文件,测试账号密码:sa / 123456");
		System.out.println();
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

启动项目

4、测试访问 ​

(1) 依次启动 SSO-Server 与 SSO-Client,然后从浏览器访问:http://sa-sso-client1.com:9002/

(注:先前版本文档测试demo端口号为9001,后为了方便区分三种模式改为了9002,因此出现文字描述与截图端口号不一致情况,请注意甄别,后不再赘述)

sso-client-index.png

(2) 首次打开,提示当前未登录,我们点击 登录 按钮,页面会被重定向到登录中心

sso-server-auth.png

(3) SSO-Server提示我们在认证中心尚未登录,我们点击 登录 按钮进行模拟登录

(4) SSO-Server认证中心登录成功,系统重定向回 client

sso-client-index-ok.png

(5) 页面被重定向至Client端首页,并提示登录成功,至此,Client1应用已单点登录成功!

(6) 我们再次访问Client2:http://sa-sso-client2.com:9002/

sso-client2-index.png

(7) 提示未登录,我们点击 登录 按钮,会直接提示登录成功

sso-client2-index-ok.png

(8) 同样的方式,我们打开Client3,也可以直接登录成功:http://sa-sso-client3.com:9002/

sso-client3-index-ok.png

至此,测试完毕!

可以看出,除了在Client1端我们需要手动登录一次之外,在Client2端和Client3端都是可以无需再次认证,直接登录成功的。

我们可以通过 F12控制台 Network 跟踪整个过程

sso-genzong

5、跨 Redis 的单点登录 ​

以上流程解决了跨域模式下的单点登录,但是后端仍然采用了共享Redis来同步会话,如果我们的架构设计中Client端与Server端无法共享Redis,又该怎么完成单点登录?

这就要采用模式三了,且往下看:SSO模式三:Http请求获取会话









发现错误? 您可以在 Gitee 或 GitHub 或 AtomGit 帮助我们完善此页文档! 或 加入讨论群 交流反馈。

我们坚信,即使再复杂的技术,也可以用清晰、干练、易懂的文字描述出它的具体细节,如果你在阅读文档时有难以理解的章节,那一定是我们还没有优化好它, 请向我们 反馈 你的困惑之处,我们将持续优化文档。


鲁ICP备18046274号-5|公安备案鲁公网安备37011202002956号
目录

本页无章节

推荐关闭
Sa-Token 商业版:轻松搭建 SSO 单点登录、OAuth2.0 统一认证、API Key 认证。全源码交付、可二开。
加入 Sa-Token 框架交流群

离线版文档历史所有版本文档Demo 示例大全下载

如果 Sa-Token 帮助到了你,希望你可以向同事、朋友推荐了解本框架,这对我们非常重要,感谢支持!

加油,工程师!