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

Sa-Token-OAuth2 Server端 API列表 ​

基于官方仓库的搭建示例,OAuth2-Server端会暴露出以下API,OAuth2-Client端可据此文档进行对接


1、模式一:授权码(Authorization Code) ​

1.1、获取授权码 ​

根据以下格式构建URL,引导用户访问 (复制时请注意删减掉相应空格和换行符)

url
http://{host}:{port}/oauth2/authorize
	?response_type=code
	&client_id={client_id}
	&redirect_uri={redirect_uri}
	&scope={scope}
	&state={state}
1
2
3
4
5
6

参数详解:

参数是否必填说明
response_type是返回类型,这里请填写:code
client_id是应用 id
redirect_uri是用户确认授权后,重定向的 url 地址
scope否具体请求的权限,多个用逗号(或空格)隔开
state否随机值,此参数会在重定向时追加到url末尾,不填不追加,如果填写则每次填写的值不可以重复

注意点:

  1. 如果用户在 OAuth-Server 端尚未登录:会被转发到登录视图,你可以参照文档或官方示例自定义登录页面。
  2. 如果 scope 参数为空,或者请求的 scope 用户近期已确认授权过,则无需用户再次确认,达到静默授权的效果,否则需要用户手动确认,服务器才可以下放 code 授权码。

用户确认授权之后,会被重定向至redirect_uri,并追加 code 参数与 state 参数,形如:

url
redirect_uri?code={code}&state={state}
1

Code 授权码具有以下特点:

  1. 每次授权产生的 Code 码都不一样。
  2. Code 码用完即废,不能二次使用。
  3. 一个 Code 的有效期默认为五分钟,超时自动作废。
  4. 每次授权产生新 Code 码,会导致旧 Code 码立即作废,即使旧 Code 码尚未使用。
RestAPI 登录接口:/oauth2/doLogin

如果用户在 OAuth-Server 端尚未登录,则会被阻塞在登录界面,开始登录,需要在页面上调用/oauth2/doLogin完成登录(此接口非 OAuth2 标准协议接口)

url
http://{host}:{port}/oauth2/doLogin
	?name={name}
	&pwd={pwd}
1
2
3

参数详解:

参数是否必填说明
name否账号
pwd否密码

访问此接口将进入自定义的 cfg.doLoginHandle 函数开始登录,你只要在此函数内调用 StpUtil.login(xxx) 即代表登录成功。

另外需要注意:此接口并非只能携带 name、pwd 参数,因为你可以在方法里通过 SaHolder.getRequest().getParam("xxx") 来获取前端提交的其它参数。

RestAPI 确认授权接口:/oauth2/doConfirm

如果 oauth-client 端申请的 scope 在 OAuth-Server 端需要用户手动确认授权,则会被阻塞在授权界面, 需要在页面上调用/oauth2/doConfirm完成授权(此接口非 OAuth2 标准协议接口)

url
http://{host}:{port}/oauth2/doConfirm
    ?client_id={value}
    &scope={value}
    &build_redirect_uri={true|false}
    &response_type={value}
    &redirect_uri={value}
    &state={value}
1
2
3
4
5
6
7

参数详解:

参数是否必填说明
client_id是应用 id
scope是具体确认的权限,多个用逗号(或空格)隔开
response_type是取 url 上的 response_type 参数来提交
redirect_uri是取 url 上的 redirect_uri 参数来提交
build_redirect_uri否是否立即构建 redirect_uri 授权地址,取值:true / false (默认)
state否取 url 上的 state 参数来提交

此接口有两种调用方式,均需提交 client_id、scope、response_type、redirect_uri 参数(可直接取当前授权页 URL 上的 query 参数),区别仅在于是否立即构建授权地址:

方式一:不提供 build_redirect_uri(或设为 false),仅确认授权,返回结果代表是否确认授权成功:

js
{
    code: 200, 
    msg: 'ok', 
    data: null,
}
1
2
3
4
5

确认成功后,需再访问 /oauth2/authorize 完成授权跳转。

方式二:指定 build_redirect_uri: true,并同时提供 state 等参数, 此时返回结果包括最终的 code 授权地址:

js
{
    code: 200, 
    msg: 'ok', 
    data: null,
	redirect_uri: 'http://sa-oauth-client.com:8002/?code=n12TTc1M9REfJVqKm0wewDz0tNZDBhE1A90irOJmxD0zb92pdhUK8NghJfuC'
}
1
2
3
4
5
6

前端在 ajax 回调函数中直接使用 location.href=res.redirect_uri 跳转即可,无需再重复访问 /oauth2/authorize 接口。

1.2、根据授权码获取 Access-Token ​

获得 Code 码后,我们可以通过以下接口,获取到用户的 Access-Token、Refresh-Token 等信息。

url
http://{host}:{port}/oauth2/token
	?grant_type=authorization_code
	&client_id={client_id}
	&client_secret={client_secret}
	&code={code}
1
2
3
4
5

参数详解:

参数是否必填说明
grant_type是授权类型,这里请填写:authorization_code
client_id是应用 id
client_secret是应用秘钥
code是步骤 1.1 中获取到的授权码

也可以通过 Basic Authorization 方式提交 client 信息,格式为在请求 header 头添加 Authorization 参数:

js
header['Authorization'] = base64(`${client_id}:${client_secret}`);
1

接口返回示例:

js
{
    "code": 200,    // 200表示请求成功,非200标识请求失败, 以下不再赘述 
    "msg": "ok",
    "data": null,
    "token_type": "Bearer",
    "access_token": "Gly7mnnXSdCxkOqmOwcA5SbG6ZtPmJVX7ZgSn1pidhRmnenBEgxbWJS8VWxA",     // Access-Token值
    "refresh_token": "EuYNwpxdc18MpaZLPyhFeyAyzr2IOWEr4q3QUGgPWqdJujQqvohjQEDJpwOm",    // Refresh-Token值
    "expires_in": 7199,                  // Access-Token剩余有效期,单位秒  
    "refresh_expires_in": 2591999,       // Refresh-Token剩余有效期,单位秒  
    "client_id": "1001",                 // 应用 id
    "scope": "userinfo"                  // 此令牌包含的权限
}
1
2
3
4
5
6
7
8
9
10
11
12

1.3、根据 Refresh-Token 刷新 Access-Token (如果需要的话) ​

Access-Token的有效期较短,如果每次过期都需要重新授权的话,会比较影响用户体验,因此我们可以在后台通过Refresh-Token 刷新 Access-Token

url
http://{host}:{port}/oauth2/refresh
	?grant_type=refresh_token
	&client_id={client_id}
	&client_secret={client_secret}
	&refresh_token={refresh_token}
1
2
3
4
5

参数详解:

参数是否必填说明
grant_type是授权类型,这里请填写:refresh_token
client_id是应用 id
client_secret是应用秘钥
refresh_token是步骤1.2中获取到的 Refresh-Token 值

接口返回值同章节1.2,此处不再赘述

1.4、回收 Access-Token (如果需要的话) ​

在A ccess-Token 过期之前主动将其回收

url
http://{host}:{port}/oauth2/revoke
	?client_id={client_id}
	&client_secret={client_secret}
	&access_token={access_token}
1
2
3
4

参数详解:

参数是否必填说明
client_id是应用 id
client_secret是应用秘钥
access_token是步骤1.2中获取到的Access-Token值

返回值样例:

js
{
    "code": 200,
    "msg": "ok",
    "data": null
}
1
2
3
4
5

1.5、根据 Access-Token 获取相应用户的账号信息 ​

注:此接口非 OAuth2 标准协议接口,为官方仓库 demo 模拟接口,正式项目中大家可以根据此样例,自定义需要的接口及参数

url
http://{host}:{port}/oauth2/userinfo?access_token={access_token}
1

返回值样例:

js
{
    "code": 200,
    "msg": "ok",
	"nickname": "shengzhang_",         // 账号昵称
	"avatar": "http://xxx.com/1.jpg",  // 头像地址
	"age": "18",                       // 年龄
	"sex": "男",                       // 性别
	"address": "山东省 青岛市 城阳区"   // 所在城市 
}
1
2
3
4
5
6
7
8
9

除了直接在 url 中以 query 参数方式提交 access_token,你也可以在 Authorization 请求头以 Bearer Token 方式提交:

js
header['Authorization'] = 'Bearer access_token';
1

2、模式二:隐藏式(Implicit) ​

根据以下格式构建URL,引导用户访问:

url
http://{host}:{port}/oauth2/authorize
	?response_type=token
	&client_id={client_id}
	&redirect_uri={redirect_uri}
	&scope={scope}
	&state={state}
1
2
3
4
5
6

参数详解:

参数是否必填说明
response_type是返回类型,这里请填写:token
client_id是应用 id
redirect_uri是用户确认授权后,重定向的url地址
scope否具体请求的权限,多个用逗号(或空格)隔开
state否随机值,此参数会在重定向时追加到url末尾,不填不追加,如果填写则每次填写的值不可以重复

此模式会越过授权码的步骤,直接返回 Access-Token 到前端页面,形如:

url
redirect_uri#token=xxxx-xxxx-xxxx-xxxx
1

注意 token 是以 # 锚参数的形式拼接到 url 上的。

3、模式三:密码式(Password) ​

首先在Client端构建表单,让用户输入 Server 端的账号和密码,然后在 Client 端访问接口

url
http://{host}:{port}/oauth2/token
	?grant_type=password
	&client_id={client_id}
	&client_secret={client_secret}
	&username={username}
	&password={password}
	&scope={scope}
1
2
3
4
5
6
7

参数详解:

参数是否必填说明
grant_type是返回类型,这里请填写:password
client_id是应用 id
client_secret是应用秘钥
username是用户的 OAuth2-Server 端账号
password是用户的 OAuth2-Server 端密码
scope否具体请求的权限,多个用逗号(或空格)隔开

接口返回示例:

js
{
    "code": 200,	// 200表示请求成功,非200标识请求失败, 以下不再赘述 
    "msg": "ok",
	"access_token": "7Ngo1Igg6rieWwAmWMe4cxT7j8o46mjyuabuwLETuAoN6JpPzPO2i3PVpEVJ",     // Access-Token 值
	"refresh_token": "ZMG7QbuCVtCIn1FAJuDbgEjsoXt5Kqzii9zsPeyahAmoir893ARA4rbmeR66",    // Refresh-Token 值
	"expires_in": 7199,                 // Access-Token 剩余有效期,单位秒  
	"refresh_expires_in": 2591999,      // Refresh-Token 剩余有效期,单位秒  
	"client_id": "1001",                // 应用 id
	"scope": "",                        // 此令牌包含的权限
}
1
2
3
4
5
6
7
8
9
10

重写认证处理器

在正式项目中,password 认证模式需要重写 PasswordGrantTypeHandler 处理器,在后面的 自定义 grant_type 章节我们会详细介绍

4、模式四:凭证式(Client Credentials) ​

以上三种模式获取的都是用户的 Access-Token,代表用户对第三方应用的授权, 在OAuth2.0中还有一种针对 Client级别的授权, 即:Client-Token,代表应用自身的资源授权

在 Client 端的后台访问以下接口:

url
http://{host}:{port}/oauth2/client_token
	?grant_type=client_credentials
	&client_id={client_id}
	&client_secret={client_secret}
	&scope={scope}
1
2
3
4
5

参数详解:

参数是否必填说明
grant_type是返回类型,这里请填写:client_credentials
client_id是应用 id
client_secret是应用秘钥
scope否具体请求的权限,多个用逗号(或空格)隔开

接口返回值样例:

js
{
    "code": 200,
    "msg": "ok",
	"client_token": "HmzPtaNuIqGrOdudWLzKJRSfPadN497qEJtanYwE7ZvHQWDy0jeoZJuDIiqO",	// Client-Token 值
	"expires_in": 7199,     // Token剩余有效时间,单位秒 
	"client_id": "1001",    // 应用 id
	"scope": null           // 包含权限 
}
1
2
3
4
5
6
7
8

注:Client-Token具有延迟作废特性,即:在每次获取最新Client-Token的时候,旧Client-Token不会立即过期,而是作为Lower-Client-Token再次储存起来, 资源请求方只要携带其中之一便可通过Token校验,这种特性保证了在大量并发请求时不会出现“新旧Token交替造成的授权失效”, 保证了服务的高可用。









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

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


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

本页无章节

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

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

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

加油,工程师!