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。提供售后技术支持。

搭建OAuth2-Server ​


1、准备工作 ​

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

url
127.0.0.1 sa-oauth-server.com
127.0.0.1 sa-oauth-client.com
1
2

2、引入依赖 ​

创建SpringBoot项目 sa-token-demo-oauth2-server(不会的同学自行百度或参考仓库示例:Sa-Token 集成示例大全下载 获取全套 Demo),引入 pom.xml 依赖:

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 OAuth2.0 模块 -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-oauth2</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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

注:Redis 相关依赖是非必须的,如果集成了 redis,可以让你更细致的观察到 sa-token-oauth2 的底层数据格式。

3、开放服务 ​

1、新建SaOAuth2ServerController

java
/**
 * Sa-Token OAuth2 Server端 控制器 
 */
@RestController
public class SaOAuth2ServerController {

	// OAuth2-Server 端:处理所有 OAuth2 相关请求
	@RequestMapping("/oauth2/*")
	public Object request() {
		System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
		return SaOAuth2ServerProcessor.instance.dister();
	}

	// Sa-Token OAuth2 定制化配置 
	@Autowired
	public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
		
		// 添加 client 信息 
		oauth2Server.addClient(
			new SaClientModel()
				.setClientId("1001")    // client id
				.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")    // client 秘钥
				.addAllowRedirectUris("*")    // 所有允许授权的 url
				.addContractScopes("openid", "userid", "userinfo")    // 所有签约的权限
				.addAllowGrantTypes(	 // 所有允许的授权模式
						GrantType.authorization_code, // 授权码式
						GrantType.implicit,  // 隐式式
						GrantType.refresh_token,  // 刷新令牌
						GrantType.password,  // 密码式
						GrantType.client_credentials  // 客户端模式
				)
		);
		
		// 可以添加更多 client 信息,只要保持 clientId 唯一就行了
		// oauth2Server.addClient(...)
		
		// 配置:未登录时返回的View 
		SaOAuth2Strategy.instance.notLoginView = () -> {
			// 简化模拟表单
			String doLoginCode =
					"fetch(`/oauth2/doLogin?name=${document.querySelector('#name').value}&pwd=${document.querySelector('#pwd').value}`) " +
							" .then(res => res.json()) " +
							" .then(res => { if(res.code === 200) { location.reload() } else { alert(res.msg) } } )";
			String res =
					"<h2>当前客户端在 OAuth-Server 认证中心尚未登录,请先登录</h2>" +
							"用户:<input id='name' /> <br> " +
							"密码:<input id='pwd' /> <br>" +
							"<button onclick=\"" + doLoginCode + "\">登录</button>";
			return res;
		};
		
		// 配置:登录处理函数 
		SaOAuth2Strategy.instance.doLoginHandle = (name, pwd) -> {
			if("sa".equals(name) && "123456".equals(pwd)) {
				StpUtil.login(10001);
				return SaResult.ok();
			}
			return SaResult.error("账号名或密码错误");
		};
		
		// 配置:确认授权时返回的 view 
		SaOAuth2Strategy.instance.confirmView = (clientId, scopes) -> {
			String scopeStr = SaFoxUtil.convertListToString(scopes);
			String yesCode =
					"fetch('/oauth2/doConfirm' + location.search, {method: 'POST'})" +
					".then(res => res.json())" +
					".then(res => location.reload())";
			String res = "<p>应用 " + clientId + " 请求授权:" + scopeStr + ",是否同意?</p>"
					+ "<p>" +
					"		<button onclick=\"" + yesCode + "\">同意</button>" +
					"		<button onclick='history.back()'>拒绝</button>" +
					"</p>";
			return res;
		};
	}
	
}
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

注意:

  • 在 doLoginHandle 函数里如果要获取 name, pwd 以外的参数,可通过 SaHolder.getRequest().getParam("xxx") 来获取。
  • 你可以在 框架配置 了解有关 SaClientModel 对象所有属性的详细定义。

2、全局异常处理

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

3、创建启动类:

java
/**
 * 启动:Sa-OAuth2 Server端 
 */
@SpringBootApplication 
public class SaOAuth2ServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(SaOAuth2ServerApplication.class, args);
		System.out.println("\nSa-Token-OAuth2 Server端启动成功,配置如下:");
		System.out.println(SaOAuth2Manager.getServerConfig());
	}
}
1
2
3
4
5
6
7
8
9
10
11

启动项目

4、访问测试 ​

1、由于暂未搭建Client端,我们可以使用 Sa-Token 官网作为重定向URL进行测试:

url
http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.com&scope=openid
1

2、由于首次访问,我们在OAuth-Server端暂未登录,会被转发到登录视图

sa-oauth2-server-login-view

3、输入 sa/123456 进行登录之后,会提示我们确认授权 sa-oauth2-server-scope

4、点击同意授权之后,我们会被重定向至 redirect_uri 页面,并携带了code参数

sa-oauth2-server-code

4、我们拿着code参数,访问以下地址:

url
http://sa-oauth-server.com:8000/oauth2/token?grant_type=authorization_code&client_id=1001&client_secret=aaaa-bbbb-cccc-dddd-eeee&code={code}
1

将得到 Access-Token、Refresh-Token、openid等授权信息:

js
{
  "code": 200,
  "msg": "ok",
  "data": null,
  "token_type": "Bearer",
  "access_token": "cAls8jnBLmeo5yuCUMwb8zxaSsQPPzGINXF3NOCjCqFHplr6hagdT6A5HeR2",
  "refresh_token": "L2rPbJ3aaOXwaB4Zu0EGWNz5EjVNpw5u2oMP9CS2IEap7rR3Hb76ZqqHS07J",
  "expires_in": 7199,
  "refresh_expires_in": 2591999,
  "client_id": "1001",
  "scope": "openid",
  "openid": "ded91dc189a437dd1bac2274be167d50"
}
1
2
3
4
5
6
7
8
9
10
11
12
13

测试完毕

5、运行官方示例 ​

以上代码只是简单模拟了一下OAuth2.0的授权流程,现在,我们运行一下官方示例,里面有制作好的UI界面

  • OAuth2-Server端: /sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/ 源码链接
  • OAuth2-Client端: /sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-client/ 源码链接

依次启动OAuth2-Server 与 OAuth2-Client,然后从浏览器访问:http://sa-oauth-client.com:8002

sa-oauth2-client-index

如图,可以针对OAuth2.0四种模式进行详细测试

6、OAuth2 前端测试页 ​

OAuth2 前端测试页: /sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-client-h5/源码链接

此示例允许你在前端自由配置 OAuth-Client 端所需的各个参数,方便对 OAuth2 四种模式的测试。

sa-oauth2-client-index

视频讲解:OAuth2 四种模式 前端测试页









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

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


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

本页无章节

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

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

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

加油,工程师!