新增OAuth2.0模块常用方法说明

This commit is contained in:
click33 2021-07-24 01:49:23 +08:00
parent 64beb7a18a
commit 5d5e2a5d52
7 changed files with 111 additions and 61 deletions

View File

@ -41,7 +41,8 @@
- **OAuth2.0**
- [OAuth2.0简述](/oauth2/readme)
- [OAuth2-Server搭建](/oauth2/oauth2-server)
- [OAuth2-API列表](/oauth2/oauth2-api)
- [OAuth2-Server端-API列表](/oauth2/oauth2-api)
- [OAuth2-二次开发说明](/oauth2/oauth2-dev)
- **微服务**
- [分布式Session会话](/micro/dcs-session)

View File

@ -0,0 +1,46 @@
# Sa-Token-OAuth2 Server端 二次开发用到的所有函数说明
官方示例只提供了基本的授权流程以及userinfo资源的开放如果您需要开放更多的接口则二次开发时用到以下相关API方法
---
## Sa-OAuth2 模块常用方法
``` java
// 根据 id 获取 Client 信息, 如果 Client 为空,则抛出异常
SaOAuth2Util.checkClientModel(clientId);
// 获取 Access-Token如果Access-Token为空则抛出异常
SaOAuth2Util.checkAccessToken(accessToken);
// 获取 Client-Token如果Client-Token为空则抛出异常
SaOAuth2Util.checkClientToken(clientToken);
// 获取 Access-Token 所代表的LoginId
SaOAuth2Util.getLoginIdByAccessToken(accessToken);
// 校验:指定 Access-Token 是否具有指定 Scope
SaOAuth2Util.checkScope(accessToken, scopes);
// 根据 code码 生成 Access-Token
SaOAuth2Util.generateAccessToken(code);
// 根据 Refresh-Token 生成一个新的 Access-Token
SaOAuth2Util.refreshAccessToken(refreshToken);
// 构建 Client-Token
SaOAuth2Util.generateClientToken(clientId, scope);
// 回收 Access-Token
SaOAuth2Util.revokeAccessToken(accessToken);
// 持久化:用户授权记录
SaOAuth2Util.saveGrantScope(clientId, loginId, scope);
// 获取Refresh-Token Model
SaOAuth2Util.getRefreshToken(refreshToken);
```
详情请参考源码:[码云SaOAuth2Util.java](https://gitee.com/dromara/sa-token/blob/dev/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Util.java)

View File

@ -1,59 +0,0 @@
# 微服务相关
Sa-Token 在微服务下的解决方案
---
### 分布式会话
分布式架构下的第一个难题便是数据同步,单机版的`Session`在分布式环境下一般不能正常工作,为此我们需要对框架做一些特定的处理。
首先我们要明白,分布式环境下为什么`Session`会失效?因为用户在一个节点对会话做出的更改无法实时同步到其它的节点,
这就导致一个很严重的问题:如果用户在节点一上已经登录成功,那么当下一次的请求落在节点二上时,对节点二来讲,此用户仍然是未登录状态。
要怎么解决这个问题呢?目前的主流方案有四种:
1. **Session同步**:只要一个节点的数据发生了改变,就强制同步到其它所有节点
2. **Session粘滞**:通过一定的算法,保证一个用户的所有请求都稳定的落在一个节点之上,对这个用户来讲,就好像还是在访问一个单机版的服务
3. **建立会话中心**将Session存储在专业的缓存中间件上使每个节点都变成了无状态服务例如`Redis`
4. **颁发无状态token**放弃Session机制将用户数据直接写入到令牌本身上使会话数据做到令牌自解释例如`jwt`
该如何选择一个合适的方案?
- 方案一:性能消耗太大,不太考虑
- 方案二:需要从网关处动手,与框架无关
- 方案三Sa-Token 整合`Redis`非常简单,详见章节:[集成Redis](/up/integ-redis)
- 方案四:详见官方仓库中 Sa-Token 整合`jwt`的示例
由于`jwt`模式不在服务端存储数据,对于比较复杂的业务可能会功能受限,因此更加推荐使用方案三
### 微服务网关鉴权
由于大多数常见网关组件基于`webflux`编写,从底层上脱离了"ServletAPI"模型(如`Gateway`、`ShenYu`等这就导致很多底层依赖ServletAPI的权限认证框架无法在网关处使用。
为此`Sa-Token`自`v1.16.0`版本开始提供了`Reactor响应式模型`web框架的starter依赖包你可以据此轻松完成网关鉴权需求
详细请参考:[全局过滤器](/up/global-filter)
### 依赖引入说明
虽然在[开始]章节已经说明了依赖引入规则但是交流群里不少小伙伴提出bug解决到最后发现都是因为依赖引入错误引起的此处再次重点强调一下
**在微服务架构中使用Sa-Token时网关和内部服务要分开引入Sa-Token依赖不要直接在顶级父pom中引入Sa-Token**
总体来讲,需要关注的依赖就是两个:`sa-token-spring-boot-starter` 和 `sa-token-reactor-spring-boot-starter`,至于怎么分辨我们需要引入哪个呢?这个要看你使用的基础框架
对于内部基础服务来讲我们一般都是使用SpringBoot默认的web模块SpringMVC因为这个SpringMVC是基于Servlet模型的在这里我们需要引入的是`sa-token-spring-boot-starter`
对于网关服务,大体来讲分为两种:
- 一种是基于Servlet模型的Zuul我们需要引入的是`sa-token-spring-boot-starter`,详细戳:[在SpringBoot环境集成](/start/example)
- 一种是基于Reactor模型的SpringCloud Gateway、ShenYu 等等,我们需要引入的是:`sa-token-reactor-spring-boot-starter`**并且注册全局过滤器!**,详细戳:[在WebFlux环境集成](/start/webflux-example)
切不可直接在一个项目里同时引入这两个依赖,否则会造成项目无法启动

View File

@ -92,6 +92,7 @@ PS两者的区别在于**`方式1会覆盖yml中的配置方式2会与y
| isPrint | Boolean | true | 是否在初始化配置时打印版本字符画 |
| isLog | Boolean | false | 是否打印操作日志 |
| jwtSecretKey | String | null | jwt秘钥 (只有集成 sa-token-temp-jwt 模块时此参数才会生效) |
| idTokenTimeout | long | 86400 | Id-Token的有效期 (单位: 秒) |
| sso | Object | new SaSsoConfig() | SSO 单点登录相关配置 |

View File

@ -9,7 +9,11 @@ import cn.dev33.satoken.action.SaTokenAction;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.context.SaTokenContext;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.id.SaIdTemplate;
import cn.dev33.satoken.id.SaIdUtil;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.sso.SaSsoTemplate;
import cn.dev33.satoken.sso.SaSsoUtil;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.temp.SaTempInterface;
@ -90,6 +94,26 @@ public class SaBeanInject {
public void setSaTemp(SaTempInterface saTemp) {
SaManager.setSaTemp(saTemp);
}
/**
* 注入 Sa-Id-Token 模块 Bean
*
* @param saIdTemplate saIdTemplate对象
*/
@Autowired(required = false)
public void setSaIdTemplate(SaIdTemplate saIdTemplate) {
SaIdUtil.saIdTemplate = saIdTemplate;
}
/**
* 注入 Sa-Token-SSO 单点登录模块 Bean
*
* @param saSsoTemplate saSsoTemplate对象
*/
@Autowired(required = false)
public void setSaSsoTemplate(SaSsoTemplate saSsoTemplate) {
SaSsoUtil.saSsoTemplate = saSsoTemplate;
}
/**
* 利用自动注入特性获取Spring框架内部使用的路由匹配器

View File

@ -13,9 +13,13 @@ import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaCheckSafe;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.id.SaIdTemplate;
import cn.dev33.satoken.id.SaIdUtil;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.solon.integration.SaContextForSolon;
import cn.dev33.satoken.solon.integration.SaTokenMethodInterceptor;
import cn.dev33.satoken.sso.SaSsoTemplate;
import cn.dev33.satoken.sso.SaSsoUtil;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.temp.SaTempInterface;
@ -38,7 +42,6 @@ public class XPluginImp implements Plugin {
SaTokenConfig saTokenConfig = Solon.cfg().getBean("sa-token", SaTokenConfig.class);
SaManager.setConfig(saTokenConfig);
//注入容器交互Bean
SaManager.setSaTokenContext(new SaContextForSolon());
@ -66,6 +69,16 @@ public class XPluginImp implements Plugin {
Aop.getAsyn(SaTempInterface.class, bw->{
SaManager.setSaTemp(bw.raw());
});
// Sa-Token-Id 身份凭证模块 Bean
Aop.getAsyn(SaIdTemplate.class, bw->{
SaIdUtil.saIdTemplate = bw.raw();
});
// Sa-Token-SSO 单点登录模块 Bean
Aop.getAsyn(SaSsoTemplate.class, bw->{
SaSsoUtil.saSsoTemplate = bw.raw();
});
}
}

View File

@ -9,7 +9,11 @@ import cn.dev33.satoken.action.SaTokenAction;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.context.SaTokenContext;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.id.SaIdTemplate;
import cn.dev33.satoken.id.SaIdUtil;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.sso.SaSsoTemplate;
import cn.dev33.satoken.sso.SaSsoUtil;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.temp.SaTempInterface;
@ -90,6 +94,26 @@ public class SaBeanInject {
public void setSaTemp(SaTempInterface saTemp) {
SaManager.setSaTemp(saTemp);
}
/**
* 注入 Sa-Id-Token 模块 Bean
*
* @param saIdTemplate saIdTemplate对象
*/
@Autowired(required = false)
public void setSaIdTemplate(SaIdTemplate saIdTemplate) {
SaIdUtil.saIdTemplate = saIdTemplate;
}
/**
* 注入 Sa-Token-SSO 单点登录模块 Bean
*
* @param saSsoTemplate saSsoTemplate对象
*/
@Autowired(required = false)
public void setSaSsoTemplate(SaSsoTemplate saSsoTemplate) {
SaSsoUtil.saSsoTemplate = saSsoTemplate;
}
/**
* 利用自动注入特性获取Spring框架内部使用的路由匹配器