From 26393d17dc975706b0c259088e977893992d988c Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Tue, 26 Apr 2022 18:59:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20json=20=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E5=99=A8=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/dev33/satoken/SaManager.java | 20 ++++ .../cn/dev33/satoken/json/SaJsonTemplate.java | 21 ++++ .../json/SaJsonTemplateDefaultImpl.java | 22 ++++ sa-token-doc/doc/_sidebar.md | 1 + sa-token-doc/doc/sso/readme.md | 13 +-- sa-token-doc/doc/sso/sso-apidoc.md | 106 ++++++++++++++++++ sa-token-doc/doc/sso/sso-server.md | 98 +--------------- .../pom.xml | 8 ++ .../satoken/reactor/spring/SaBeanInject.java | 13 ++- .../reactor/spring/SaBeanRegister.java | 12 ++ .../spring/json/SaJsonTemplateForJackson.java | 38 +++++++ .../cn/dev33/satoken/spring/SaBeanInject.java | 15 ++- .../dev33/satoken/spring/SaBeanRegister.java | 14 ++- .../spring/json/SaJsonTemplateForJackson.java | 38 +++++++ 14 files changed, 306 insertions(+), 113 deletions(-) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java create mode 100644 sa-token-doc/doc/sso/sso-apidoc.md create mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/json/SaJsonTemplateForJackson.java create mode 100644 sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java b/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java index d687b838..2ba3b674 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java @@ -11,6 +11,8 @@ import cn.dev33.satoken.context.second.SaTokenSecondContext; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl; import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.json.SaJsonTemplate; +import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl; import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.listener.SaTokenListenerDefaultImpl; import cn.dev33.satoken.stp.StpInterface; @@ -171,6 +173,24 @@ public class SaManager { } return saTemp; } + + /** + * JSON 转换器 Bean + */ + private volatile static SaJsonTemplate saJsonTemplate; + public static void setSaJsonTemplate(SaJsonTemplate saJsonTemplate) { + SaManager.saJsonTemplate = saJsonTemplate; + } + public static SaJsonTemplate getSaJsonTemplate() { + if (saJsonTemplate == null) { + synchronized (SaManager.class) { + if (saJsonTemplate == null) { + setSaJsonTemplate(new SaJsonTemplateDefaultImpl()); + } + } + } + return saJsonTemplate; + } /** * StpLogic集合, 记录框架所有成功初始化的StpLogic diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java new file mode 100644 index 00000000..462cb7d2 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java @@ -0,0 +1,21 @@ +package cn.dev33.satoken.json; + +import java.util.Map; + +/** + * JSON 转换器 + * + * @author kong + * + */ +public interface SaJsonTemplate { + + /** + * 将 json 字符串解析为 Map + * + * @param jsonStr json 字符串 + * @return 转换后的 Map 对象 + */ + public Map parseJsonToMap(String jsonStr); + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java new file mode 100644 index 00000000..36552d0c --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java @@ -0,0 +1,22 @@ +package cn.dev33.satoken.json; + +import java.util.Map; + +import cn.dev33.satoken.exception.ApiDisabledException; + +/** + * JSON 相关操作接口 + * + * @author kong + * + */ +public class SaJsonTemplateDefaultImpl implements SaJsonTemplate { + + /** + * 将 json 字符串解析为 Map + */ + public Map parseJsonToMap(String jsonStr) { + throw new ApiDisabledException("未实现具体的 json 转换器"); + }; + +} diff --git a/sa-token-doc/doc/_sidebar.md b/sa-token-doc/doc/_sidebar.md index d04967d6..a2ebd112 100644 --- a/sa-token-doc/doc/_sidebar.md +++ b/sa-token-doc/doc/_sidebar.md @@ -35,6 +35,7 @@ - **单点登录** - [单点登录简述](/sso/readme) - [搭建统一认证中心:SSO-Server](/sso/sso-server) + - [SSO-Server 认证中心开放接口](/sso/sso-apidoc) - [SSO模式一 共享Cookie同步会话](/sso/sso-type1) - [SSO模式二 URL重定向传播会话](/sso/sso-type2) - [SSO模式三 Http请求获取会话](/sso/sso-type3) diff --git a/sa-token-doc/doc/sso/readme.md b/sa-token-doc/doc/sso/readme.md index d9d5d8d8..2246002e 100644 --- a/sa-token-doc/doc/sso/readme.md +++ b/sa-token-doc/doc/sso/readme.md @@ -15,7 +15,7 @@ ### 架构选型 -对于单点登录,网上教程大多以CAS模式为主,其实对于不同的系统架构,实现单点登录的步骤也大为不同,Sa-Token 由简入难将其划分为三种模式: +Sa-Token-SSO 由简入难划分为三种模式,解决不同架构下的 SSO 接入问题: | 系统架构 | 采用模式 | 简介 | 文档链接 | | :-------- | :-------- | :-------- | :-------- | @@ -27,16 +27,15 @@ 1. 前端同域:就是指多个系统可以部署在同一个主域名之下,比如:`c1.domain.com`、`c2.domain.com`、`c3.domain.com`。 2. 后端同Redis:就是指多个系统可以连接同一个Redis。PS:这里并不需要把所有项目的数据都放在同一个Redis中,Sa-Token提供了 **`[权限缓存与业务缓存分离]`** 的解决方案,详情戳:[Alone独立Redis插件](http://sa-token.dev33.cn/doc/index.html#/plugin/alone-redis)。 3. 如果既无法做到前端同域,也无法做到后端同Redis,那么只能走模式三,Http请求获取会话(Sa-Token对SSO提供了完整的封装,你只需要按照示例从文档上复制几段代码便可以轻松集成)。 -4. 技术选型一定要根据系统架构对症下药,切不可胡乱选择。 ### Sa-Token-SSO 特性 -1. API简单易用,文档介绍详细,且提供直接可用的集成示例 -2. 支持三种模式,不论是否跨域、是否共享Redis、是否前后端分离,都可以完美解决 -3. 安全性高:内置域名校验、Ticket校验、秘钥校验等,杜绝`Ticket劫持`、`Token窃取`等常见攻击手段(文档讲述攻击原理和防御手段) -4. 不丢参数:笔者曾试验多个单点登录框架,均有参数丢失的情况,比如重定向之前是:`http://a.com?id=1&name=2`,登录成功之后就变成了:`http://a.com?id=1`,Sa-Token-SSO内有专门的算法保证了参数不丢失,登录成功之后原路返回页面 +1. API 简单易用,文档介绍详细,且提供直接可用的集成示例。 +2. 支持三种模式,不论是否跨域、是否共享Redis、是否前后端分离,都可以完美解决。 +3. 安全性高:内置域名校验、Ticket校验、秘钥校验等,杜绝`Ticket劫持`、`Token窃取`等常见攻击手段(文档讲述攻击原理和防御手段)。 +4. 不丢参数:笔者曾试验多个单点登录框架,均有参数丢失的情况,比如重定向之前是:`http://a.com?id=1&name=2`,登录成功之后就变成了:`http://a.com?id=1`,Sa-Token-SSO内有专门的算法保证了参数不丢失,登录成功之后原路返回页面。 5. 无缝集成:由于Sa-Token本身就是一个权限认证框架,因此你可以只用一个框架同时解决`权限认证` + `单点登录`问题,让你不再到处搜索:xxx单点登录与xxx权限认证如何整合…… -6. 高可定制:Sa-Token-SSO模块对代码架构侵入性极低,结合Sa-Token本身的路由拦截特性,你可以非常轻松的定制化开发 +6. 高可定制:Sa-Token-SSO模块对代码架构侵入性极低,结合Sa-Token本身的路由拦截特性,你可以非常轻松的定制化开发。 diff --git a/sa-token-doc/doc/sso/sso-apidoc.md b/sa-token-doc/doc/sso/sso-apidoc.md new file mode 100644 index 00000000..df6dd035 --- /dev/null +++ b/sa-token-doc/doc/sso/sso-apidoc.md @@ -0,0 +1,106 @@ +# SSO-Server 认证中心开放接口 + +如果你的 SSO-Server 端和 SSO-Client 端都使用 Sa-Token-SSO 搭建,那么你可以直接跳过本章,开始 [SSO模式一 共享Cookie同步会话](/sso/sso-type1) 的学习。 + +如果你仅在 SSO-Server 端使用 Sa-Token-SSO 搭建,而 SSO-Client 端使用其它框架的话,那么你就需要手动调用 http 请求来对接 SSO-Server 认证中心, +下面的 API 列表将给你的对接步骤做一份参考。 + +--- + + +### 1、单点登录授权地址 +``` url +http://{host}:{port}/sso/auth +``` + +接收参数: + +| 参数 | 是否必填 | 说明 | +| :-------- | :-------- | :-------- | +| redirect | 是 | 登录成功后的重定向地址,一般填写 location.href(从哪来回哪去) | +| mode | 否 | 授权模式,取值 [simple, ticket],simple=登录后直接重定向,ticket=带着ticket参数重定向,默认值为ticket | + +访问接口后有两种情况: +- 情况一:当前会话在 SSO 认证中心未登录,会进入登录页开始登录。 +- 情况二:当前会话在 SSO 认证中心已登录,会被重定向至 `redirect` 地址,并携带 `ticket` 参数。 + + +### 2、RestAPI 登录接口 +``` url +http://{host}:{port}/sso/doLogin +``` + +接收参数: + +| 参数 | 是否必填 | 说明 | +| :-------- | :-------- | :-------- | +| name | 是 | 用户名 | +| pwd | 是 | 密码 | + +此接口属于 RestAPI (使用ajax访问),会进入后端配置的 `setDoLoginHandle` 函数中,另外需要注意: +此接口并非只能携带 name、pwd 参数,因为你可以在 setDoLoginHandle 函数里通过 `SaHolder.getRequest().getParam("xxx")` 来获取其它参数。 + + +### 3、Ticket 校验接口 +此接口仅配置模式三 `(isHttp=true)` 时打开 + +``` url +http://{host}:{port}/sso/checkTicket +``` + +接收参数: + +| 参数 | 是否必填 | 说明 | +| :-------- | :-------- | :-------- | +| ticket | 是 | 在步骤 5.1 中授权重定向时的 ticket 参数 | +| ssoLogoutCall | 否 | 单点注销时的回调通知地址,只在SSO模式三单点注销时需要携带此参数| + +返回值场景: +- 返回空,代表校验失败。 +- 返回具体的 loginId,例如10001,代表校验成功,值为此 ticket 码代表的用户id。 + + +### 4、单点注销接口 +``` url +http://{host}:{port}/sso/logout +``` + +接受参数: + +| 参数 | 是否必填 | 说明 | +| :-------- | :-------- | :-------- | +| loginId | 否 | 要注销的账号id | +| secretkey | 否 | 接口通信秘钥 | +| back | 否 | 注销成功后的重定向地址 | + + +此接口有两种调用方式 + +##### 方式一:在 Client 的前端页面引导用户直接跳转,并带有 back 参数 +例如:`http://{host}:{port}/sso/logout?back=xxx`,代表用户注销成功后返回back地址 + +##### 方式二:在 Client 的后端通过 http 工具来调用 +例如:`http://{host}:{port}/sso/logout?loginId={value}&secretkey={value}`,代表注销 账号=loginId 的账号,返回json数据结果,形如: + +``` js +{ + "code": 200, // 200表示请求成功,非200标识请求失败 + "msg": "单点注销成功", + "data": null +} +``` + +
+ +SSO 认证中心只有这四个接口,接下来让我一起来看一下 Client 端的对接流程:[SSO模式一 共享Cookie同步会话](/sso/sso-type1) + + + + + + + + + + + diff --git a/sa-token-doc/doc/sso/sso-server.md b/sa-token-doc/doc/sso/sso-server.md index b998bc91..8a5103ab 100644 --- a/sa-token-doc/doc/sso/sso-server.md +++ b/sa-token-doc/doc/sso/sso-server.md @@ -190,104 +190,10 @@ public class SaSsoServerApplication { 默认账号密码为:`sa / 123456`,先别着急点击登录,因为我们还没有搭建对应的 Client 端项目, 真实项目中我们是不会直接从浏览器访问 `/sso/auth` 授权地址的,我们需要在 Client 端点击登录按钮重定向而来。 -现在我们先来看看除了 `/sso/auth` 统一授权地址,这个 SSO-Server 认证中心还开放了哪些API。 - -### 5、API 列表 - -如果你仅仅使用 Sa-Token 搭建 SSO-Server 端,而 Client 端使用其它框架的话,那么下面的 API 列表将给你的对接步骤做一份参考。 - -如果你在 Client 端也用到了 Sa-Token 框架,那么你可以选择跳过本小节,Sa-Token 对 Client 端也提供了相应的封装,你可以直接开始学习:[SSO模式一 共享Cookie同步会话](/sso/sso-type1) - - -#### 5.1、单点登录授权地址 -``` url -http://{host}:{port}/sso/auth -``` - -接收参数: - -| 参数 | 是否必填 | 说明 | -| :-------- | :-------- | :-------- | -| redirect | 是 | 登录成功后的重定向地址,一般填写 location.href(从哪来回哪去) | -| mode | 否 | 授权模式,取值 [simple, ticket],simple=登录后直接重定向,ticket=带着ticket参数重定向,默认值为ticket | - -访问接口后有两种情况: -- 情况一:当前会话在 SSO 认证中心未登录,会进入登录页开始登录。 -- 情况二:当前会话在 SSO 认证中心已登录,会被重定向至 `redirect` 地址,并携带 `ticket` 参数。 - - -#### 5.2、RestAPI 登录接口 -``` url -http://{host}:{port}/sso/doLogin -``` - -接收参数: - -| 参数 | 是否必填 | 说明 | -| :-------- | :-------- | :-------- | -| name | 是 | 用户名 | -| pwd | 是 | 密码 | - -此接口属于 RestAPI (使用ajax访问),会进入后端配置的 `setDoLoginHandle` 函数中,另外需要注意: -此接口并非只能携带 name、pwd 参数,因为你可以在 setDoLoginHandle 函数里通过 `SaHolder.getRequest().getParam("xxx")` 来获取其它参数。 - - -#### 5.3、Ticket 校验接口 -此接口仅配置模式三 `(isHttp=true)` 时打开 - -``` url -http://{host}:{port}/sso/checkTicket -``` - -接收参数: - -| 参数 | 是否必填 | 说明 | -| :-------- | :-------- | :-------- | -| ticket | 是 | 在步骤 5.1 中授权重定向时的 ticket 参数 | -| ssoLogoutCall | 否 | 单点注销时的回调通知地址,只在SSO模式三单点注销时需要携带此参数| - -返回值场景: -- 返回空,代表校验失败。 -- 返回具体的 loginId,例如10001,代表校验成功,值为此 ticket 码代表的用户id。 - - -#### 5.4、单点注销接口 -``` url -http://{host}:{port}/sso/logout -``` - -接受参数: - -| 参数 | 是否必填 | 说明 | -| :-------- | :-------- | :-------- | -| loginId | 否 | 要注销的账号id | -| secretkey | 否 | 接口通信秘钥 | -| back | 否 | 注销成功后的重定向地址 | - - -此接口有两种调用方式 - -##### 方式一:在 Client 的前端页面引导用户直接跳转,并带有 back 参数 -例如:`http://{host}:{port}/sso/logout?back=xxx`,代表用户注销成功后返回back地址 - -##### 方式二:在 Client 的后端通过 http 工具来调用 -例如:`http://{host}:{port}/sso/logout?loginId={value}&secretkey={value}`,代表注销 账号=loginId 的账号,返回json数据结果,形如: - -``` js -{ - "code": 200, // 200表示请求成功,非200标识请求失败 - "msg": "单点注销成功", - "data": null -} -``` - -
- -SSO 认证中心只有这四个接口,接下来让我一起来看一下 Client 端的对接流程:[SSO模式一 共享Cookie同步会话](/sso/sso-type1) - - +--- +现在我们先来看看除了 `/sso/auth` 统一授权地址,这个 SSO-Server 认证中心还开放了哪些API:[SSO-Server 认证中心开放接口](/sso/sso-apidoc)。 diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml b/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml index 15dac83c..da135390 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml @@ -59,6 +59,14 @@ true + + + com.fasterxml.jackson.core + jackson-databind + 2.12.6.1 + true + + org.springframework.boot 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 4f1cb643..44d5ac53 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 @@ -13,6 +13,7 @@ import cn.dev33.satoken.context.second.SaTokenSecondContextCreator; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.id.SaIdTemplate; import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpLogic; @@ -113,10 +114,20 @@ public class SaBeanInject { * @param saBasicTemplate saBasicTemplate对象 */ @Autowired(required = false) - public void setSaSsoTemplate(SaBasicTemplate saBasicTemplate) { + public void setSaBasicTemplate(SaBasicTemplate saBasicTemplate) { SaBasicUtil.saBasicTemplate = saBasicTemplate; } + /** + * 注入自定义的 JSON 转换器 Bean + * + * @param saJsonTemplate JSON 转换器 + */ + @Autowired(required = false) + public void setSaJsonTemplate(SaJsonTemplate saJsonTemplate) { + SaManager.setSaJsonTemplate(saJsonTemplate); + } + /** * 注入自定义的 StpLogic * @param stpLogic / diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanRegister.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanRegister.java index 7cdff979..3937be72 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanRegister.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanRegister.java @@ -6,6 +6,8 @@ import org.springframework.context.annotation.Bean; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.context.SaTokenContextForThreadLocal; +import cn.dev33.satoken.json.SaJsonTemplate; +import cn.dev33.satoken.reactor.spring.json.SaJsonTemplateForJackson; /** * 注册Sa-Token所需要的Bean @@ -44,4 +46,14 @@ public class SaBeanRegister { }; } + /** + * 获取 json 转换器 Bean (Jackson版) + * + * @return json 转换器 Bean (Jackson版) + */ + @Bean + public SaJsonTemplate getSaJsonTemplateForJackson() { + return new SaJsonTemplateForJackson(); + } + } diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/json/SaJsonTemplateForJackson.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/json/SaJsonTemplateForJackson.java new file mode 100644 index 00000000..7d3cc806 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/json/SaJsonTemplateForJackson.java @@ -0,0 +1,38 @@ +package cn.dev33.satoken.reactor.spring.json; + +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.json.SaJsonTemplate; + +/** + * JSON 转换器, Jackson 版实现 + * + * @author kong + * @date: 2022-4-26 + */ +public class SaJsonTemplateForJackson implements SaJsonTemplate { + + /** + * 底层 Mapper 对象 + */ + public ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 将 json 字符串解析为 Map + */ + @Override + public Map parseJsonToMap(String jsonStr) { + try { + @SuppressWarnings("unchecked") + Map map = objectMapper.readValue(jsonStr, Map.class); + return map; + } catch (JsonProcessingException e) { + throw new SaTokenException(e); + } + } + +} 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 5d70f8e4..ab2e81ea 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 @@ -13,9 +13,8 @@ import cn.dev33.satoken.context.second.SaTokenSecondContextCreator; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.id.SaIdTemplate; import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.json.SaJsonTemplate; 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.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; @@ -115,20 +114,20 @@ public class SaBeanInject { * @param saBasicTemplate saBasicTemplate对象 */ @Autowired(required = false) - public void setSaSsoTemplate(SaBasicTemplate saBasicTemplate) { + public void setSaBasicTemplate(SaBasicTemplate saBasicTemplate) { SaBasicUtil.saBasicTemplate = saBasicTemplate; } /** - * 注入 Sa-Token-SSO 单点登录模块 Bean + * 注入自定义的 JSON 转换器 Bean * - * @param saSsoTemplate saSsoTemplate对象 + * @param saJsonTemplate JSON 转换器 */ @Autowired(required = false) - public void setSaSsoTemplate(SaSsoTemplate saSsoTemplate) { - SaSsoUtil.saSsoTemplate = saSsoTemplate; + public void setSaJsonTemplate(SaJsonTemplate saJsonTemplate) { + SaManager.setSaJsonTemplate(saJsonTemplate); } - + /** * 注入自定义的 StpLogic * @param stpLogic / diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java index db4805cc..125d76ff 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java @@ -5,6 +5,8 @@ import org.springframework.context.annotation.Bean; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.context.SaTokenContext; +import cn.dev33.satoken.json.SaJsonTemplate; +import cn.dev33.satoken.spring.json.SaJsonTemplateForJackson; /** * 注册Sa-Token所需要的Bean @@ -26,7 +28,7 @@ public class SaBeanRegister { } /** - * 获取容器交互Bean (Spring版) + * 获取上下文Bean (Spring版) * * @return 容器交互Bean (Spring版) */ @@ -35,4 +37,14 @@ public class SaBeanRegister { return new SaTokenContextForSpring(); } + /** + * 获取 json 转换器 Bean (Jackson版) + * + * @return json 转换器 Bean (Jackson版) + */ + @Bean + public SaJsonTemplate getSaJsonTemplateForJackson() { + return new SaJsonTemplateForJackson(); + } + } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java new file mode 100644 index 00000000..a809fdf7 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java @@ -0,0 +1,38 @@ +package cn.dev33.satoken.spring.json; + +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.json.SaJsonTemplate; + +/** + * JSON 转换器, Jackson 版实现 + * + * @author kong + * @date: 2022-4-26 + */ +public class SaJsonTemplateForJackson implements SaJsonTemplate { + + /** + * 底层 Mapper 对象 + */ + public ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 将 json 字符串解析为 Map + */ + @Override + public Map parseJsonToMap(String jsonStr) { + try { + @SuppressWarnings("unchecked") + Map map = objectMapper.readValue(jsonStr, Map.class); + return map; + } catch (JsonProcessingException e) { + throw new SaTokenException(e); + } + } + +}