diff --git a/sa-token-doc/doc/_sidebar.md b/sa-token-doc/doc/_sidebar.md index 3c974322..be0ac459 100644 --- a/sa-token-doc/doc/_sidebar.md +++ b/sa-token-doc/doc/_sidebar.md @@ -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) diff --git a/sa-token-doc/doc/oauth2/oauth2-dev.md b/sa-token-doc/doc/oauth2/oauth2-dev.md new file mode 100644 index 00000000..4952d237 --- /dev/null +++ b/sa-token-doc/doc/oauth2/oauth2-dev.md @@ -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) + + diff --git a/sa-token-doc/doc/senior/dcs.md b/sa-token-doc/doc/senior/dcs.md deleted file mode 100644 index 9bb39358..00000000 --- a/sa-token-doc/doc/senior/dcs.md +++ /dev/null @@ -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) - -切不可直接在一个项目里同时引入这两个依赖,否则会造成项目无法启动 - - - - - - - - - - diff --git a/sa-token-doc/doc/use/config.md b/sa-token-doc/doc/use/config.md index 0beac887..4de2f5a9 100644 --- a/sa-token-doc/doc/use/config.md +++ b/sa-token-doc/doc/use/config.md @@ -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 单点登录相关配置 | diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanInject.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanInject.java index c33f0e07..0eaf4cf3 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanInject.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanInject.java @@ -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框架内部使用的路由匹配器 diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java index 208aa442..3e1b9322 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java @@ -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(); + }); } } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java index 887b47ef..0b3eae22 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java @@ -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框架内部使用的路由匹配器