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 1185a889..d0c56888 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 @@ -13,6 +13,7 @@ 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.same.SaSameTemplate; import cn.dev33.satoken.sign.SaSignTemplate; import cn.dev33.satoken.sign.SaSignTemplateDefaultImpl; import cn.dev33.satoken.stp.StpInterface; @@ -191,6 +192,24 @@ public class SaManager { } return saSignTemplate; } + + /** + * Same-Token Bean + */ + private volatile static SaSameTemplate saSameTemplate; + public static void setSaSameTemplate(SaSameTemplate saSameTemplate) { + SaManager.saSameTemplate = saSameTemplate; + } + public static SaSameTemplate getSaSameTemplate() { + if (saSameTemplate == null) { + synchronized (SaManager.class) { + if (saSameTemplate == null) { + setSaSameTemplate(new SaSameTemplate()); + } + } + } + return saSameTemplate; + } /** * StpLogic集合, 记录框架所有成功初始化的StpLogic diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/application/SaApplication.java b/sa-token-core/src/main/java/cn/dev33/satoken/application/SaApplication.java index f4b6b021..df8c11ea 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/application/SaApplication.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/application/SaApplication.java @@ -63,7 +63,7 @@ public class SaApplication implements SaSetValueInterface { public List keys() { // 查出来 String prefix = splicingDataKey(""); - List list = SaManager.getSaTokenDao().searchData(prefix, "", -1, 0, true); + List list = SaManager.getSaTokenDao().searchData(prefix, "", 0, -1, true); // 裁减掉固定前缀 int prefixLength = prefix.length(); diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java index 53026e9a..6ecd1ea6 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java @@ -74,11 +74,6 @@ public class SaTokenConfig implements Serializable { * jwt秘钥 (只有集成 jwt 模块时此参数才会生效) */ private String jwtSecretKey; - - /** - * Id-Token的有效期 (单位: 秒) - */ - private long idTokenTimeout = 60 * 60 * 24; /** * Http Basic 认证的账号和密码 @@ -88,8 +83,14 @@ public class SaTokenConfig implements Serializable { /** 配置当前项目的网络访问地址 */ private String currDomain; - /** 是否校验Id-Token(部分rpc插件有效) */ - private Boolean checkIdToken = false; + /** + * Same-Token 的有效期 (单位: 秒) + */ + private long sameTokenTimeout = 60 * 60 * 24; + + /** 是否校验Same-Token(部分rpc插件有效) */ + private Boolean checkSameToken = false; + /** * Cookie配置对象 @@ -389,22 +390,6 @@ public class SaTokenConfig implements Serializable { return this; } - /** - * @return Id-Token的有效期 (单位: 秒) - */ - public long getIdTokenTimeout() { - return idTokenTimeout; - } - - /** - * @param idTokenTimeout Id-Token的有效期 (单位: 秒) - * @return 对象自身 - */ - public SaTokenConfig setIdTokenTimeout(long idTokenTimeout) { - this.idTokenTimeout = idTokenTimeout; - return this; - } - /** * @return Http Basic 认证的账号和密码 */ @@ -438,18 +423,34 @@ public class SaTokenConfig implements Serializable { } /** - * @return 是否校验Id-Token(部分rpc插件有效) + * @return Same-Token 的有效期 (单位: 秒) */ - public Boolean getCheckIdToken() { - return checkIdToken; + public long getSameTokenTimeout() { + return sameTokenTimeout; } /** - * @param checkIdToken 是否校验Id-Token(部分rpc插件有效) - * @return 对象自身 + * @param sameTokenTimeout Same-Token 的有效期 (单位: 秒) + * @return 对象自身 */ - public SaTokenConfig setCheckIdToken(Boolean checkIdToken) { - this.checkIdToken = checkIdToken; + public SaTokenConfig setSameTokenTimeout(long sameTokenTimeout) { + this.sameTokenTimeout = sameTokenTimeout; + return this; + } + + /** + * @return 是否校验Same-Token(部分rpc插件有效) + */ + public Boolean getCheckSameToken() { + return checkSameToken; + } + + /** + * @param checkSameToken 是否校验Same-Token(部分rpc插件有效) + * @return 对象自身 + */ + public SaTokenConfig setCheckSameToken(Boolean checkSameToken) { + this.checkSameToken = checkSameToken; return this; } @@ -490,10 +491,10 @@ public class SaTokenConfig implements Serializable { + ", isPrint=" + isPrint + ", isLog=" + isLog + ", jwtSecretKey=" + jwtSecretKey - + ", idTokenTimeout=" + idTokenTimeout + ", basic=" + basic + ", currDomain=" + currDomain - + ", checkIdToken=" + checkIdToken + + ", sameTokenTimeout=" + sameTokenTimeout + + ", checkSameToken=" + checkSameToken + ", cookie=" + cookie + "]"; } @@ -519,5 +520,44 @@ public class SaTokenConfig implements Serializable { return this; } + /** + *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 getSameTokenTimeout() ,使用方式保持不变

+ * @return Id-Token的有效期 (单位: 秒) + */ + @Deprecated + public long getIdTokenTimeout() { + return sameTokenTimeout; + } + + /** + *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 setSameTokenTimeout() ,使用方式保持不变

+ * @param idTokenTimeout Id-Token的有效期 (单位: 秒) + * @return 对象自身 + */ + @Deprecated + public SaTokenConfig setIdTokenTimeout(long idTokenTimeout) { + this.sameTokenTimeout = idTokenTimeout; + return this; + } + + /** + *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 getCheckSameToken() ,使用方式保持不变

+ * @return 是否校验Id-Token(部分rpc插件有效) + */ + @Deprecated + public Boolean getCheckIdToken() { + return checkSameToken; + } + + /** + *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 setCheckSameToken() ,使用方式保持不变

+ * @param checkIdToken 是否校验Id-Token(部分rpc插件有效) + * @return 对象自身 + */ + @Deprecated + public SaTokenConfig setCheckIdToken(Boolean checkIdToken) { + this.checkSameToken = checkIdToken; + return this; + } } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/IdTokenInvalidException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/IdTokenInvalidException.java index dd8aa087..543274a6 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/IdTokenInvalidException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/IdTokenInvalidException.java @@ -1,10 +1,12 @@ package cn.dev33.satoken.exception; /** + *

本类设计已过时,未来版本可能移除此类,请及时更换为 SameTokenInvalidException ,使用方式保持不变

* 一个异常:代表提供的 Id-Token 无效 * * @author kong */ +@Deprecated public class IdTokenInvalidException extends SaTokenException { /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/SameTokenInvalidException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/SameTokenInvalidException.java new file mode 100644 index 00000000..160cbf3a --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/SameTokenInvalidException.java @@ -0,0 +1,24 @@ +package cn.dev33.satoken.exception; + +/** + * 一个异常:代表提供的 Same-Token 无效 + * + * @author kong + * @since 2022-10-24 + */ +public class SameTokenInvalidException extends SaTokenException { + + /** + * 序列化版本号 + */ + private static final long serialVersionUID = 6806129545290130144L; + + /** + * 一个异常:代表提供的 Same-Token 无效 + * @param message 异常描述 + */ + public SameTokenInvalidException(String message) { + super(message); + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java index 39cc4659..a3417aed 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java @@ -6,11 +6,14 @@ import cn.dev33.satoken.exception.IdTokenInvalidException; import cn.dev33.satoken.util.SaFoxUtil; /** + *

本类设计已过时,未来版本可能移除此类,请及时更换为 SaSameTemplate ,使用方式保持不变

+ * * Sa-Token-Id 身份凭证模块 *

身份凭证的获取与校验,可用于微服务内部调用鉴权 * @author kong * */ +@Deprecated public class SaIdTemplate { /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java index af822348..a9ca80a8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java @@ -1,10 +1,13 @@ package cn.dev33.satoken.id; /** + *

本类设计已过时,未来版本可能移除此类,请及时更换为 SaSameUtil ,使用方式保持不变

+ * * Sa-Token-Id 身份凭证模块-工具类 * @author kong * */ +@Deprecated public class SaIdUtil { private SaIdUtil(){} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/same/SaSameTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/same/SaSameTemplate.java new file mode 100644 index 00000000..4b0fe36e --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/same/SaSameTemplate.java @@ -0,0 +1,174 @@ +package cn.dev33.satoken.same; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.exception.SameTokenInvalidException; +import cn.dev33.satoken.util.SaFoxUtil; + +/** + * Sa Same-Token 同源系统身份认证模块 - 模板方法类 + * + *

解决同源系统互相调用时的身份认证校验, 例如:微服务网关请求转发鉴权、微服务RPC调用鉴权 + * + * @author kong + * @since 2022-10-24 + */ +public class SaSameTemplate { + + /** + * 提交 Same-Token 时,建议使用的参数名称 + */ + public static final String SAME_TOKEN = "SA-SAME-TOKEN"; + + // -------------------- 获取 & 校验 + + /** + * 获取当前 Same-Token, 如果不存在,则立即创建并返回 + * @return / + */ + public String getToken() { + String currentToken = getTokenNh(); + if(SaFoxUtil.isEmpty(currentToken)) { + // 注意这里的自刷新不能做到高并发可用 + currentToken = refreshToken(); + } + return currentToken; + } + + /** + * 判断一个 Same-Token 是否有效 + * @param token / + * @return / + */ + public boolean isValid(String token) { + // 1、 如果传入的 token 为空,则立即返回 false + if(SaFoxUtil.isEmpty(token)) { + return false; + } + + // 2、 验证当前 Same-Token 及 Past-Same-Token + return token.equals(getToken()) || token.equals(getPastTokenNh()); + } + + /** + * 校验一个 Same-Token 是否有效 (如果无效则抛出异常) + * @param token / + */ + public void checkToken(String token) { + if(isValid(token) == false) { + token = (token == null ? "" : token); + throw new SameTokenInvalidException("无效Same-Token:" + token); + } + } + + /** + * 校验当前 Request 上下文提供的 Same-Token 是否有效 (如果无效则抛出异常) + */ + public void checkCurrentRequestToken() { + checkToken(SaHolder.getRequest().getHeader(SAME_TOKEN)); + } + + /** + * 刷新一次 Same-Token (注意集群环境中不要多个服务重复调用) + * @return 刷新后产生的新 Same-Token + */ + public String refreshToken() { + + // 1. 先将当前 Same-Token 写入到 Past-Same-Token 中 + String sameToken = getTokenNh(); + if(SaFoxUtil.isEmpty(sameToken) == false) { + savePastToken(sameToken, getTokenTimeout()); + } + + // 2. 再刷新当前 Same-Token + String newSameToken = createToken(); + saveToken(newSameToken); + + // 3. 返回新的 Same-Token + return newSameToken; + } + + + // ------------------------------ 保存Token + + /** + * 保存 Same-Token + * @param token / + */ + public void saveToken(String token) { + if(SaFoxUtil.isEmpty(token)) { + return; + } + SaManager.getSaTokenDao().set(splicingTokenSaveKey(), token, SaManager.getConfig().getSameTokenTimeout()); + } + + /** + * 保存 Past-Same-Token + * @param token token + * @param timeout 有效期(单位:秒) + */ + public void savePastToken(String token, long timeout){ + if(SaFoxUtil.isEmpty(token)) { + return; + } + SaManager.getSaTokenDao().set(splicingPastTokenSaveKey(), token, timeout); + } + + + // -------------------- 获取Token + + /** + * 获取 Same-Token,不做任何处理 + * @return / + */ + public String getTokenNh() { + return SaManager.getSaTokenDao().get(splicingTokenSaveKey()); + } + + /** + * 获取 Past-Same-Token,不做任何处理 + * @return / + */ + public String getPastTokenNh() { + return SaManager.getSaTokenDao().get(splicingPastTokenSaveKey()); + } + + /** + * 获取 Same-Token 的剩余有效期 (单位:秒) + * @return / + */ + public long getTokenTimeout() { + return SaManager.getSaTokenDao().getTimeout(splicingTokenSaveKey()); + } + + + // -------------------- 创建Token + + /** + * 创建一个 Same-Token + * @return Token + */ + public String createToken() { + return SaFoxUtil.getRandomString(64); + } + + + // -------------------- 拼接key + + /** + * 拼接key:Same-Token 的存储 key + * @return key + */ + public String splicingTokenSaveKey() { + return SaManager.getConfig().getTokenName() + ":var:same-token"; + } + + /** + * 拼接key:次级 Same-Token 的存储 key + * @return key + */ + public String splicingPastTokenSaveKey() { + return SaManager.getConfig().getTokenName() + ":var:past-same-token"; + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/same/SaSameUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/same/SaSameUtil.java new file mode 100644 index 00000000..55729930 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/same/SaSameUtil.java @@ -0,0 +1,83 @@ +package cn.dev33.satoken.same; + +import cn.dev33.satoken.SaManager; + +/** + * Sa Same-Token 同源系统身份认证模块 - 工具类 + * + *

解决同源系统互相调用时的身份认证校验, 例如:微服务网关请求转发鉴权、微服务RPC调用鉴权 + * + * @author kong + * @since 2022-10-24 + */ +public class SaSameUtil { + + private SaSameUtil(){} + + /** + * 提交 Same-Token 时,建议使用的参数名称 + */ + public static final String SAME_TOKEN = SaSameTemplate.SAME_TOKEN; + + // -------------------- 获取 & 校验 + + /** + * 获取当前 Same-Token, 如果不存在,则立即创建并返回 + * @return / + */ + public static String getToken() { + return SaManager.getSaSameTemplate().getToken(); + } + + /** + * 判断一个 Same-Token 是否有效 + * @param token / + * @return / + */ + public static boolean isValid(String token) { + return SaManager.getSaSameTemplate().isValid(token); + } + + /** + * 校验一个 Same-Token 是否有效 (如果无效则抛出异常) + * @param token / + */ + public static void checkToken(String token) { + SaManager.getSaSameTemplate().checkToken(token); + } + + /** + * 校验当前 Request 上下文提供的 Same-Token 是否有效 (如果无效则抛出异常) + */ + public static void checkCurrentRequestToken() { + SaManager.getSaSameTemplate().checkCurrentRequestToken(); + } + + /** + * 刷新一次 Same-Token (注意集群环境中不要多个服务重复调用) + * @return 刷新后产生的新 Same-Token + */ + public static String refreshToken() { + return SaManager.getSaSameTemplate().refreshToken(); + } + + + // -------------------- 获取Token + + /** + * 获取 Same-Token,不做任何处理 + * @return / + */ + public static String getTokenNh() { + return SaManager.getSaSameTemplate().getTokenNh(); + } + + /** + * 获取 Past-Same-Token,不做任何处理 + * @return / + */ + public static String getPastTokenNh() { + return SaManager.getSaSameTemplate().getPastTokenNh(); + } + +} diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/SaTokenApplication.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/SaTokenApplication.java index 0df2e994..228e0bc2 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/SaTokenApplication.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/SaTokenApplication.java @@ -17,5 +17,5 @@ public class SaTokenApplication { SpringApplication.run(SaTokenApplication.class, args); System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); } - + } diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java index 00ce6931..de4768c9 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java @@ -82,5 +82,5 @@ public class SaTokenConfigure implements WebMvcConfigurer { }) ; } - + } diff --git a/sa-token-doc/_sidebar.md b/sa-token-doc/_sidebar.md index 70f7401c..ad64f509 100644 --- a/sa-token-doc/_sidebar.md +++ b/sa-token-doc/_sidebar.md @@ -56,7 +56,7 @@ - **微服务** - [分布式Session会话](/micro/dcs-session) - [网关统一鉴权](/micro/gateway-auth) - - [内部服务外网隔离](/micro/id-token) + - [内部服务外网隔离](/micro/same-token) - [依赖引入说明](/micro/import-intro) - **插件** diff --git a/sa-token-doc/micro/id-token.md b/sa-token-doc/micro/same-token.md similarity index 68% rename from sa-token-doc/micro/id-token.md rename to sa-token-doc/micro/same-token.md index 187e33a9..892b51f9 100644 --- a/sa-token-doc/micro/id-token.md +++ b/sa-token-doc/micro/same-token.md @@ -14,9 +14,9 @@ Sa-Token提供两种解决方案: 1. 使用 OAuth2.0 模式的凭证式,将 Client-Token 用作各个服务的身份凭证进行权限校验 -2. 使用 Id-Token 模块提供的身份校验能力,完成服务间的权限认证 +2. 使用 Same-Token 模块提供的身份校验能力,完成服务间的权限认证 -本篇主要讲解方案二 `Id-Token` 模块的整合步骤,其鉴权流程与 OAuth2.0 类似,不过使用方式上更加简洁(希望使用方案一的同学可参考Sa-OAuth2模块,此处不再赘述) +本篇主要讲解方案二 `Same-Token` 模块的整合步骤,其鉴权流程与 OAuth2.0 类似,不过使用方式上更加简洁(希望使用方案一的同学可参考Sa-OAuth2模块,此处不再赘述) ### 二、网关转发鉴权 @@ -88,12 +88,12 @@ implementation 'org.apache.commons:commons-pool2' ``` -##### 2、网关处添加Id-Token +##### 2、网关处添加Same-Token 为网关添加全局过滤器: ``` java /** - * 全局过滤器,为请求添加 Id-Token + * 全局过滤器,为请求添加 Same-Token */ @Component public class ForwardAuthFilter implements GlobalFilter { @@ -102,15 +102,15 @@ public class ForwardAuthFilter implements GlobalFilter { ServerHttpRequest newRequest = exchange .getRequest() .mutate() - // 为请求追加 Id-Token 参数 - .header(SaIdUtil.ID_TOKEN, SaIdUtil.getToken()) + // 为请求追加 Same-Token 参数 + .header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()) .build(); ServerWebExchange newExchange = exchange.mutate().request(newRequest).build(); return chain.filter(newExchange); } } ``` -此过滤器会为 Request 请求头追加 `Id-Token` 参数,这个参数会被转发到子服务 +此过滤器会为 Request 请求头追加 `Same-Token` 参数,这个参数会被转发到子服务 ##### 3、在子服务里校验参数 @@ -129,9 +129,9 @@ public class SaTokenConfigure implements WebMvcConfigurer { .addInclude("/**") .addExclude("/favicon.ico") .setAuth(obj -> { - // 校验 Id-Token 身份凭证 —— 以下两句代码可简化为:SaIdUtil.checkCurrentRequestToken(); - String token = SaHolder.getRequest().getHeader(SaIdUtil.ID_TOKEN); - SaIdUtil.checkToken(token); + // 校验 Same-Token 身份凭证 —— 以下两句代码可简化为:SaSameUtil.checkCurrentRequestToken(); + String token = SaHolder.getRequest().getHeader(SaSameUtil.SAME_TOKEN); + SaSameUtil.checkToken(token); }) .setError(e -> { return SaResult.error(e.getMessage()); @@ -143,14 +143,14 @@ public class SaTokenConfigure implements WebMvcConfigurer { 启动网关与子服务,访问测试: -> 如果通过网关转发,可以正常访问,直接访问子服务会提示:`无效Id-Token:xxx` +> 如果通过网关转发,可以正常访问,直接访问子服务会提示:`无效Same-Token:xxx` ### 三、服务内部调用鉴权 -有时候我们需要在一个服务调用另一个服务的接口,这也是需要添加`Id-Token`作为身份凭证的 +有时候我们需要在一个服务调用另一个服务的接口,这也是需要添加`Same-Token`作为身份凭证的 -在服务里添加 Id-Token 流程与网关类似,我们以RPC框架 `Feign` 为例: +在服务里添加 Same-Token 流程与网关类似,我们以RPC框架 `Feign` 为例: ##### 1、首先在调用方添加 FeignInterceptor ``` java @@ -159,10 +159,10 @@ public class SaTokenConfigure implements WebMvcConfigurer { */ @Component public class FeignInterceptor implements RequestInterceptor { - // 为 Feign 的 RCP调用 添加请求头Id-Token + // 为 Feign 的 RCP调用 添加请求头Same-Token @Override public void apply(RequestTemplate requestTemplate) { - requestTemplate.header(SaIdUtil.ID_TOKEN, SaIdUtil.getToken()); + requestTemplate.header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()); } } ``` @@ -189,63 +189,63 @@ public interface SpCfgInterface { 被调用方的代码无需更改(按照网关转发鉴权处的代码注册全局过滤器),保持启动测试即可 -### 四、Id-Token 模块详解 +### 四、Same-Token 模块详解 -Id-Token —— 专门解决身份凭证问题的一个模块,它的作用不仅局限于微服务调用场景 +Same-Token —— 专门解决同源系统互相调用时的身份认证校验,它的作用不仅局限于微服务调用场景 基本使用流程为:服务调用方获取Token,提交到请求中,被调用方取出Token进行校验:Token一致则校验通过,否则拒绝服务 首先我们预览一下此模块的相关API: ``` java -// 获取当前Id-Token -SaIdUtil.getToken(); +// 获取当前Same-Token +SaSameUtil.getToken(); -// 判断一个Id-Token是否有效 -SaIdUtil.isValid(token); +// 判断一个Same-Token是否有效 +SaSameUtil.isValid(token); -// 校验一个Id-Token是否有效 (如果无效则抛出异常) -SaIdUtil.checkToken(token); +// 校验一个Same-Token是否有效 (如果无效则抛出异常) +SaSameUtil.checkToken(token); -// 校验当前Request提供的Id-Token是否有效 (如果无效则抛出异常) -SaIdUtil.checkCurrentRequestToken(); +// 校验当前Request提供的Same-Token是否有效 (如果无效则抛出异常) +SaSameUtil.checkCurrentRequestToken(); -// 刷新一次Id-Token (注意集群环境中不要多个服务重复调用) -SaIdUtil.refreshToken(); +// 刷新一次Same-Token (注意集群环境中不要多个服务重复调用) +SaSameUtil.refreshToken(); -// 在 Request 上储存 Id-Token 时建议使用的key -SaIdUtil.ID_TOKEN; +// 在 Request 上储存 Same-Token 时建议使用的key +SaSameUtil.SAME_TOKEN; ``` ##### 1、疑问:这个Token保存在什么地方?有没有泄露的风险?Token为永久有效还是临时有效? -Id-Token 默认随 Sa-Token 数据一起保存在Redis中,理论上不会存在泄露的风险,每个Token默认有效期只有一天 +Same-Token 默认随 Sa-Token 数据一起保存在Redis中,理论上不会存在泄露的风险,每个Token默认有效期只有一天 -##### 2、如何主动刷新Id-Token,例如:五分钟、两小时刷新一次? -Id-Token 刷新间隔越短,其安全性越高,每个Token的默认有效期为一天,在一天后再次获取会自动产生一个新的Token +##### 2、如何主动刷新Same-Token,例如:五分钟、两小时刷新一次? +Same-Token 刷新间隔越短,其安全性越高,每个Token的默认有效期为一天,在一天后再次获取会自动产生一个新的Token -!> 需要注意的一点是:Id-Token默认的自刷新机制,并不能做到高并发可用,多个服务一起触发Token刷新可能会造成毫秒级的短暂服务失效,其只能适用于 项目开发阶段 或 低并发业务场景 +!> 需要注意的一点是:Same-Token默认的自刷新机制,并不能做到高并发可用,多个服务一起触发Token刷新可能会造成毫秒级的短暂服务失效,其只能适用于 项目开发阶段 或 低并发业务场景 -因此在微服务架构下,我们需要有专门的机制主动刷新Id-Token,保证其高可用 +因此在微服务架构下,我们需要有专门的机制主动刷新Same-Token,保证其高可用 -例如,我们可以专门起一个服务,使用定时任务来刷新Id-Token +例如,我们可以专门起一个服务,使用定时任务来刷新Same-Token ``` java /** - * Id-Token,定时刷新 + * Same-Token,定时刷新 */ @Configuration -public class SaIdTokenRefreshTask { - // 从 0 分钟开始 每隔 5 分钟执行一次 Id-Token +public class SaSameTokenRefreshTask { + // 从 0 分钟开始 每隔 5 分钟执行一次 Same-Token @Scheduled(cron = "0 0/5 * * * ? ") public void refreshToken(){ - SaIdUtil.refreshToken(); + SaSameUtil.refreshToken(); } } ``` -以上的cron表达式刷新间隔可以配置为`五分钟`、`十分钟` 或 `两小时`,只要低于Id-Token的有效期(默认为一天)即可。 +以上的cron表达式刷新间隔可以配置为`五分钟`、`十分钟` 或 `两小时`,只要低于Same-Token的有效期(默认为一天)即可。 ##### 3、如果网关携带token转发的请求在落到子服务的节点上时,恰好刷新了token,导致鉴权未通过怎么办? -Id-Token 模块在设计时,充分考虑到了这一点,在每次刷新 Token 时,旧 Token 会被作为次级 Token 存储起来, -只要网关携带的 Token 符合新旧 Token 其一即可通过认证,直至下一次刷新,新 Token 再次作为次级 Token 将此替换掉 +Same-Token 模块在每次刷新 Token 时,旧 Token 会被作为次级 Token 存储起来, +只要网关携带的 Token 符合新旧 Token 其一即可通过认证,直至下一次刷新,新 Token 再次作为次级 Token 将此替换掉。 diff --git a/sa-token-doc/more/noun-intro.md b/sa-token-doc/more/noun-intro.md index 21afced6..67766d95 100644 --- a/sa-token-doc/more/noun-intro.md +++ b/sa-token-doc/more/noun-intro.md @@ -13,7 +13,7 @@ Sa-Token 无意发明任何晦涩概念提升逼格,但在处理 issue 、Q群 - temp-token:指通过 `SaTempUtil.createToken()` 临时验证模块产生的Token,也称:临时Token。 - Access-Token:在 OAuth2 模块产生的身份令牌,也称:访问令牌、资源令牌。 - Refresh-Token:在 OAuth2 模块产生的刷新令牌,也称:刷新令牌。 -- Id-Token:在 SaIdUtil 模块生成的Token令牌,用于提供子服务外网隔离功能。 +- Same-Token:在 SaSameUtil 模块生成的Token令牌,用于提供子服务外网隔离功能。 #### 两种过期时间: diff --git a/sa-token-doc/plugin/dubbo-extend.md b/sa-token-doc/plugin/dubbo-extend.md index b67251fc..65dcaf54 100644 --- a/sa-token-doc/plugin/dubbo-extend.md +++ b/sa-token-doc/plugin/dubbo-extend.md @@ -60,9 +60,9 @@ implementation 'cn.dev33:sa-token-context-dubbo:${sa.top.version}' ### RPC调用鉴权 -在之前的 [Id-Token](/micro/id-token) 章节,我们演示了基于 Feign 的 RPC 调用鉴权,下面我们演示一下在 Dubbo 中如何集成 Id-Token 模块。 +在之前的 [Same-Token](/micro/same-token) 章节,我们演示了基于 Feign 的 RPC 调用鉴权,下面我们演示一下在 Dubbo 中如何集成 Same-Token 模块。 -其实思路和 Feign 模式一致,在 [ 调用端 ] 追加 Id-Token 参数,在 [ 被调用端 ] 校验这个 Id-Token 参数: +其实思路和 Feign 模式一致,在 [ 调用端 ] 追加 Same-Token 参数,在 [ 被调用端 ] 校验这个 Same-Token 参数: - 校验通过:调用成功。 - 校验不通过:通过失败,抛出异常。 @@ -78,18 +78,18 @@ implementation 'cn.dev33:sa-token-context-dubbo:${sa.top.version}' ``` yaml sa-token: # 打开 RPC 调用鉴权 - check-id-token: true + check-same-token: true ``` ``` properties # 打开 RPC 调用鉴权 -sa-token.check-id-token=true +sa-token.check-same-token=true ``` ##### 方式二、自建 Dubbo 过滤器校验 -此方式略显繁琐,好处是除了Id-Token,我们还可以添加其它自定义参数 (attachment)。 +此方式略显繁琐,好处是除了Same-Token,我们还可以添加其它自定义参数 (attachment)。 1、在 [ 调用端 ] 的 `\resources\META-INF\dubbo\` 目录新建 `org.apache.dubbo.rpc.Filter` 文件 ``` html @@ -105,7 +105,7 @@ import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.*; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; /** * Sa-Token 整合 Dubbo Consumer端过滤器 @@ -116,8 +116,8 @@ public class DubboConsumerFilter implements Filter { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - // 追加 Id-Token 参数 - RpcContext.getContext().setAttachment(SaIdUtil.ID_TOKEN, SaIdUtil.getToken()); + // 追加 Same-Token 参数 + RpcContext.getContext().setAttachment(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()); // 如果有其他自定义附加数据,如租户 // RpcContext.getContext().setAttachment("tenantContext", tenantContext); @@ -144,7 +144,7 @@ import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.*; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; /** * Sa-Token 整合 Dubbo Provider端过滤器 @@ -155,9 +155,9 @@ public class DubboProviderFilter implements Filter { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - // 取出 Id-Token 进行校验 - String idToken = invocation.getAttachment(SaIdUtil.ID_TOKEN); - SaIdUtil.checkToken(idToken); + // 取出 Same-Token 进行校验 + String sameToken = invocation.getAttachment(SaSameUtil.SAME_TOKEN); + SaSameUtil.checkToken(sameToken); // 取出其他自定义附加数据 // TenantContext tenantContext = invocation.getAttachment("tenantContext"); @@ -170,5 +170,5 @@ public class DubboProviderFilter implements Filter { ``` -然后我们就可以进行安全的 RPC 调用了,不带有 Id-Token 参数的调用都会抛出异常,无法调用成功。 +然后我们就可以进行安全的 RPC 调用了,不带有 Same-Token 参数的调用都会抛出异常,无法调用成功。 diff --git a/sa-token-doc/plugin/grpc-extend.md b/sa-token-doc/plugin/grpc-extend.md index 84d73506..f2af1fb1 100644 --- a/sa-token-doc/plugin/grpc-extend.md +++ b/sa-token-doc/plugin/grpc-extend.md @@ -8,7 +8,7 @@ 1. 在 [ 被调用端 ] 安全的调用 Sa-Token 相关 API。 2. 在 [ 调用端 ] 登录的会话,其登录状态可以自动传递到 [ 被调用端 ] ;在 [ 被调用端 ] 登录的会话,其登录状态可以自动回传到 [ 调用端 ] -3. id-token 安全校验 +3. Same-Token 安全校验 --- 和dubbo插件一样,具有以下限制: @@ -38,7 +38,7 @@ implementation 'cn.dev33:sa-token-context-grpc:${sa.top.version}' --- -### 开启id-token校验: +### 开启 Same-Token 校验: 直接在 `application.yml` 配置即可: @@ -46,11 +46,11 @@ implementation 'cn.dev33:sa-token-context-grpc:${sa.top.version}' ``` yaml sa-token: # 打开 RPC 调用鉴权 - check-id-token: true + check-same-token: true ``` ``` properties # 打开 RPC 调用鉴权 -sa-token.check-id-token=true +sa-token.check-same-token=true ``` \ No newline at end of file diff --git a/sa-token-doc/use/config.md b/sa-token-doc/use/config.md index baf3d37f..f5fbc7be 100644 --- a/sa-token-doc/use/config.md +++ b/sa-token-doc/use/config.md @@ -134,10 +134,10 @@ public class SaTokenConfigure { | isPrint | Boolean | true | 是否在初始化配置时打印版本字符画 | | isLog | Boolean | false | 是否打印操作日志 | | jwtSecretKey | String | null | jwt秘钥 (只有集成 `sa-token-temp-jwt` 模块时此参数才会生效),[参考:和 jwt 集成](/plugin/jwt-extend) | -| idTokenTimeout | long | 86400 | Id-Token的有效期 (单位: 秒),[参考:内部服务外网隔离](/micro/id-token) | +| sameTokenTimeout | long | 86400 | Same-Token的有效期 (单位: 秒),[参考:内部服务外网隔离](/micro/same-token) | | basic | String | "" | Http Basic 认证的账号和密码 [参考:Http Basic 认证](/up/basic-auth) | | currDomain | String | null | 配置当前项目的网络访问地址 | -| checkIdToken | Boolean | false | 是否校验Id-Token(部分rpc插件有效) | +| checkSameToken | Boolean | false | 是否校验Same-Token(部分rpc插件有效) | | cookie | Object | new SaCookieConfig() | Cookie配置对象 | Cookie相关配置: diff --git a/sa-token-plugin/sa-token-context-dubbo/pom.xml b/sa-token-plugin/sa-token-context-dubbo/pom.xml index 4bfcb873..4c241a6b 100644 --- a/sa-token-plugin/sa-token-context-dubbo/pom.xml +++ b/sa-token-plugin/sa-token-context-dubbo/pom.xml @@ -21,7 +21,6 @@ cn.dev33 sa-token-core - ${revision} diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboConsumerFilter.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboConsumerFilter.java index e8f37bb2..70c0b929 100644 --- a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboConsumerFilter.java +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboConsumerFilter.java @@ -11,7 +11,7 @@ import org.apache.dubbo.rpc.RpcException; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.SaTokenContextDefaultImpl; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaTokenConsts; @@ -28,9 +28,9 @@ public class SaTokenDubboConsumerFilter implements Filter { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - // 追加 Id-Token 参数 - if(SaManager.getConfig().getCheckIdToken()) { - RpcContext.getContext().setAttachment(SaIdUtil.ID_TOKEN, SaIdUtil.getToken()); + // 追加 Same-Token 参数 + if(SaManager.getConfig().getCheckSameToken()) { + RpcContext.getContext().setAttachment(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()); } // 1. 调用前,向下传递会话Token diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboProviderFilter.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboProviderFilter.java index e6510bfd..ba0bd635 100644 --- a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboProviderFilter.java +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboProviderFilter.java @@ -9,7 +9,7 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import cn.dev33.satoken.SaManager; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; /** * @@ -25,13 +25,13 @@ public class SaTokenDubboProviderFilter implements Filter { public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { // RPC 调用鉴权 - if(SaManager.getConfig().getCheckIdToken()) { - String idToken = invocation.getAttachment(SaIdUtil.ID_TOKEN); + if(SaManager.getConfig().getCheckSameToken()) { + String idToken = invocation.getAttachment(SaSameUtil.SAME_TOKEN); // dubbo部分协议会将参数变为小写,详细参考:https://gitee.com/dromara/sa-token/issues/I4WXQG if(idToken == null) { - idToken = invocation.getAttachment(SaIdUtil.ID_TOKEN.toLowerCase()); + idToken = invocation.getAttachment(SaSameUtil.SAME_TOKEN.toLowerCase()); } - SaIdUtil.checkToken(idToken); + SaSameUtil.checkToken(idToken); } // 开始调用 diff --git a/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/constants/GrpcContextConstants.java b/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/constants/GrpcContextConstants.java index 62ec93f7..77ad22ad 100644 --- a/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/constants/GrpcContextConstants.java +++ b/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/constants/GrpcContextConstants.java @@ -1,6 +1,6 @@ package cn.dev33.satoken.context.grpc.constants; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; import cn.dev33.satoken.util.SaTokenConsts; import io.grpc.Metadata; @@ -11,8 +11,8 @@ import io.grpc.Metadata; * @since: 2022/8/26 14:27 */ public class GrpcContextConstants { - public static final Metadata.Key SA_ID_TOKEN = - Metadata.Key.of(SaIdUtil.ID_TOKEN, Metadata.ASCII_STRING_MARSHALLER); + public static final Metadata.Key SA_SAME_TOKEN = + Metadata.Key.of(SaSameUtil.SAME_TOKEN, Metadata.ASCII_STRING_MARSHALLER); public static final Metadata.Key SA_JUST_CREATED_NOT_PREFIX = Metadata.Key.of(SaTokenConsts.JUST_CREATED_NOT_PREFIX, Metadata.ASCII_STRING_MARSHALLER); diff --git a/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcClientInterceptor.java b/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcClientInterceptor.java index 9983832e..0032938d 100644 --- a/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcClientInterceptor.java +++ b/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcClientInterceptor.java @@ -1,14 +1,23 @@ package cn.dev33.satoken.context.grpc.interceptor; +import org.springframework.core.Ordered; + import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.SaTokenContextDefaultImpl; import cn.dev33.satoken.context.grpc.constants.GrpcContextConstants; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaFoxUtil; -import io.grpc.*; +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall; +import io.grpc.ForwardingClientCallListener; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; +import io.grpc.Status; import net.devh.boot.grpc.client.interceptor.GrpcGlobalClientInterceptor; -import org.springframework.core.Ordered; /** @@ -26,9 +35,9 @@ public class SaTokenGrpcClientInterceptor implements ClientInterceptor, Ordered @Override public void start(Listener responseListener, Metadata headers) { - // 追加 Id-Token 参数 - if (SaManager.getConfig().getCheckIdToken()) { - headers.put(GrpcContextConstants.SA_ID_TOKEN, SaIdUtil.getToken()); + // 追加 Same-Token 参数 + if (SaManager.getConfig().getCheckSameToken()) { + headers.put(GrpcContextConstants.SA_SAME_TOKEN, SaSameUtil.getToken()); } // 调用前,传递会话Token diff --git a/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcServerInterceptor.java b/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcServerInterceptor.java index b0e81ac9..faa00858 100644 --- a/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcServerInterceptor.java +++ b/sa-token-plugin/sa-token-context-grpc/src/main/java/cn/dev33/satoken/context/grpc/interceptor/SaTokenGrpcServerInterceptor.java @@ -2,10 +2,15 @@ package cn.dev33.satoken.context.grpc.interceptor; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.grpc.constants.GrpcContextConstants; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaFoxUtil; -import io.grpc.*; +import io.grpc.ForwardingServerCall; +import io.grpc.Metadata; +import io.grpc.ServerCall; +import io.grpc.ServerCallHandler; +import io.grpc.ServerInterceptor; +import io.grpc.Status; import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor; /** @@ -19,9 +24,9 @@ public class SaTokenGrpcServerInterceptor implements ServerInterceptor { @Override public ServerCall.Listener interceptCall(ServerCall call, Metadata headers, ServerCallHandler next) { // RPC 调用鉴权 - if (SaManager.getConfig().getCheckIdToken()) { - String idToken = headers.get(GrpcContextConstants.SA_ID_TOKEN); - SaIdUtil.checkToken(idToken); + if (SaManager.getConfig().getCheckSameToken()) { + String sameToken = headers.get(GrpcContextConstants.SA_SAME_TOKEN); + SaSameUtil.checkToken(sameToken); } String tokenFromClient = headers.get(GrpcContextConstants.SA_JUST_CREATED_NOT_PREFIX); StpUtil.setTokenValue(tokenFromClient); 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 14ac0390..f1a09d0f 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 @@ -18,6 +18,7 @@ import cn.dev33.satoken.id.SaIdUtil; import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenListener; +import cn.dev33.satoken.same.SaSameTemplate; import cn.dev33.satoken.sign.SaSignTemplate; import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpLogic; @@ -30,6 +31,7 @@ import cn.dev33.satoken.temp.SaTempInterface; * @author kong * */ +@SuppressWarnings("deprecation") public class SaBeanInject { /** @@ -112,6 +114,16 @@ public class SaBeanInject { SaIdUtil.saIdTemplate = saIdTemplate; } + /** + * 注入 Same-Token 模块 Bean + * + * @param saSameTemplate saSameTemplate对象 + */ + @Autowired(required = false) + public void setSaIdTemplate(SaSameTemplate saSameTemplate) { + SaManager.setSaSameTemplate(saSameTemplate); + } + /** * 注入 Sa-Token Http Basic 认证模块 * 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 7991d65b..2e7bc4ca 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 @@ -21,6 +21,7 @@ import cn.dev33.satoken.id.SaIdUtil; import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenListener; +import cn.dev33.satoken.same.SaSameTemplate; import cn.dev33.satoken.sign.SaSignTemplate; import cn.dev33.satoken.solon.integration.SaTokenAnnotationInterceptor; import cn.dev33.satoken.solon.model.SaContextForSolon; @@ -96,6 +97,11 @@ public class XPluginImp implements Plugin { SaIdUtil.saIdTemplate = bw.raw(); }); + // Sa-Token Same-Token 模块 Bean + context.getWrapAsyn(SaSameTemplate.class, bw->{ + SaManager.setSaSignTemplate(bw.raw()); + }); + // Sa-Token Http Basic 认证模块 Bean context.getWrapAsyn(SaBasicTemplate.class, bw->{ SaBasicUtil.saBasicTemplate = 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 c2362bc4..af842ac3 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 @@ -18,6 +18,7 @@ import cn.dev33.satoken.id.SaIdUtil; import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenListener; +import cn.dev33.satoken.same.SaSameTemplate; import cn.dev33.satoken.sign.SaSignTemplate; import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpLogic; @@ -30,6 +31,7 @@ import cn.dev33.satoken.temp.SaTempInterface; * @author kong * */ +@SuppressWarnings("deprecation") public class SaBeanInject { /** @@ -112,6 +114,16 @@ public class SaBeanInject { SaIdUtil.saIdTemplate = saIdTemplate; } + /** + * 注入 Same-Token 模块 Bean + * + * @param saSameTemplate saSameTemplate对象 + */ + @Autowired(required = false) + public void setSaIdTemplate(SaSameTemplate saSameTemplate) { + SaManager.setSaSameTemplate(saSameTemplate); + } + /** * 注入 Sa-Token Http Basic 认证模块 * diff --git a/sa-token-test/sa-token-jwt-test/pom.xml b/sa-token-test/sa-token-jwt-test/pom.xml index 43cd6c66..49cd9ee5 100644 --- a/sa-token-test/sa-token-jwt-test/pom.xml +++ b/sa-token-test/sa-token-jwt-test/pom.xml @@ -20,12 +20,10 @@ cn.dev33 sa-token-spring-boot-starter - ${revision} cn.dev33 sa-token-jwt - ${revision} diff --git a/sa-token-test/sa-token-springboot-test/pom.xml b/sa-token-test/sa-token-springboot-test/pom.xml index aff9cce5..628ee136 100644 --- a/sa-token-test/sa-token-springboot-test/pom.xml +++ b/sa-token-test/sa-token-springboot-test/pom.xml @@ -20,30 +20,25 @@ cn.dev33 sa-token-spring-boot-starter - ${revision} - + cn.dev33 sa-token-sso - ${revision} test cn.dev33 sa-token-oauth2 - ${revision} test cn.dev33 sa-token-servlet - ${revision} cn.dev33 sa-token-core - ${revision} diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java index a26a928c..c4f7e943 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java @@ -71,8 +71,8 @@ public class SaTokenConfigTest { config.setJwtSecretKey("NgdfaXasARggr"); Assertions.assertEquals(config.getJwtSecretKey(), "NgdfaXasARggr"); - config.setIdTokenTimeout(1004); - Assertions.assertEquals(config.getIdTokenTimeout(), 1004); + config.setSameTokenTimeout(1004); + Assertions.assertEquals(config.getSameTokenTimeout(), 1004); config.setBasic("sa:123456"); Assertions.assertEquals(config.getBasic(), "sa:123456"); @@ -80,8 +80,8 @@ public class SaTokenConfigTest { config.setCurrDomain("http://127.0.0.1:8084"); Assertions.assertEquals(config.getCurrDomain(), "http://127.0.0.1:8084"); - config.setCheckIdToken(false); - Assertions.assertEquals(config.getCheckIdToken(), false); + config.setCheckSameToken(false); + Assertions.assertEquals(config.getCheckSameToken(), false); SaCookieConfig scc = new SaCookieConfig(); config.setCookie(scc); diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java index ad9abb05..398a8032 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java @@ -90,11 +90,11 @@ public class SaFoxUtilTest { // 不做分页 - List list5 = SaFoxUtil.searchList(dataList, "", "", -1, 0, true); + List list5 = SaFoxUtil.searchList(dataList, "", "", 0, -1, true); Assertions.assertEquals(list5.size(), dataList.size()); // 反序排列 list6的第一个元素 == dataList最后一个元素 - List list6 = SaFoxUtil.searchList(dataList, "", "", -1, 0, false); + List list6 = SaFoxUtil.searchList(dataList, "", "", 0, -1, false); Assertions.assertEquals(list6.get(0), dataList.get(dataList.size() - 1)); } diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/HandlerException.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/HandlerException.java index aec6870c..8a7e97ea 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/HandlerException.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/HandlerException.java @@ -4,12 +4,12 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import cn.dev33.satoken.exception.DisableServiceException; -import cn.dev33.satoken.exception.IdTokenInvalidException; import cn.dev33.satoken.exception.NotBasicAuthException; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotPermissionException; import cn.dev33.satoken.exception.NotRoleException; import cn.dev33.satoken.exception.NotSafeException; +import cn.dev33.satoken.exception.SameTokenInvalidException; import cn.dev33.satoken.util.SaResult; /** @@ -44,9 +44,9 @@ public class HandlerException { return SaResult.error().setCode(901); } - // id-token 校验失败,code=902 - @ExceptionHandler(IdTokenInvalidException.class) - public SaResult handlerIdTokenInvalidException(IdTokenInvalidException e) { + // same-token 校验失败,code=902 + @ExceptionHandler(SameTokenInvalidException.class) + public SaResult handlerSameTokenInvalidException(SameTokenInvalidException e) { return SaResult.error().setCode(902); } diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/inject/MySaIdTemplate.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/inject/MySaSameTemplate.java similarity index 54% rename from sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/inject/MySaIdTemplate.java rename to sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/inject/MySaSameTemplate.java index e9729768..e24da7ef 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/inject/MySaIdTemplate.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/configure/inject/MySaSameTemplate.java @@ -2,9 +2,9 @@ package cn.dev33.satoken.integrate.configure.inject; import org.springframework.stereotype.Component; -import cn.dev33.satoken.id.SaIdTemplate; +import cn.dev33.satoken.same.SaSameTemplate; @Component -public class MySaIdTemplate extends SaIdTemplate { +public class MySaSameTemplate extends SaSameTemplate { } diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/id/SaIdTokenController.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/same/SaSameTokenController.java similarity index 58% rename from sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/id/SaIdTokenController.java rename to sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/same/SaSameTokenController.java index ca2a4e4b..9d3100b5 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/id/SaIdTokenController.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/same/SaSameTokenController.java @@ -1,28 +1,28 @@ -package cn.dev33.satoken.integrate.id; +package cn.dev33.satoken.integrate.same; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.same.SaSameUtil; import cn.dev33.satoken.spring.SpringMVCUtil; import cn.dev33.satoken.util.SaResult; /** - * id-token Controller + * same-token Controller * * @author kong * */ @RestController -@RequestMapping("/id/") -public class SaIdTokenController { +@RequestMapping("/same/") +public class SaSameTokenController { // 获取信息 @RequestMapping("getInfo") public SaResult getInfo() { - // 获取并校验id-token - String idToken = SpringMVCUtil.getRequest().getHeader(SaIdUtil.ID_TOKEN); - SaIdUtil.checkToken(idToken); + // 获取并校验same-token + String sameToken = SpringMVCUtil.getRequest().getHeader(SaSameUtil.SAME_TOKEN); + SaSameUtil.checkToken(sameToken); // 返回信息 return SaResult.data("info=zhangsan"); } @@ -30,8 +30,8 @@ public class SaIdTokenController { // 获取信息2 @RequestMapping("getInfo2") public SaResult getInfo2() { - // 获取并校验id-token - SaIdUtil.checkCurrentRequestToken(); + // 获取并校验same-token + SaSameUtil.checkCurrentRequestToken(); // 返回信息 return SaResult.data("info=zhangsan2"); } diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/id/SaIdTokenControllerTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/same/SaSameTokenControllerTest.java similarity index 64% rename from sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/id/SaIdTokenControllerTest.java rename to sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/same/SaSameTokenControllerTest.java index ad9dfa86..a63dbd07 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/id/SaIdTokenControllerTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/integrate/same/SaSameTokenControllerTest.java @@ -1,4 +1,4 @@ -package cn.dev33.satoken.integrate.id; +package cn.dev33.satoken.integrate.same; import java.util.Map; @@ -16,19 +16,19 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import cn.dev33.satoken.SaManager; -import cn.dev33.satoken.exception.IdTokenInvalidException; -import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.exception.SameTokenInvalidException; import cn.dev33.satoken.integrate.StartUpApplication; +import cn.dev33.satoken.same.SaSameUtil; import cn.dev33.satoken.util.SaResult; /** - * id-token Controller 测试 + * same-token Controller 测试 * * @author kong * */ @SpringBootTest(classes = StartUpApplication.class) -public class SaIdTokenControllerTest { +public class SaSameTokenControllerTest { @Autowired private WebApplicationContext wac; @@ -44,73 +44,73 @@ public class SaIdTokenControllerTest { // 获取信息 @Test public void testGetInfo() { - String token = SaIdUtil.getToken(); + String token = SaSameUtil.getToken(); // 加token,能调通 - SaResult res = request("/id/getInfo", token); + SaResult res = request("/same/getInfo", token); Assertions.assertEquals(res.getCode(), 200); // 不加token,不能调通 - SaResult res2 = request("/id/getInfo", "xxx"); + SaResult res2 = request("/same/getInfo", "xxx"); Assertions.assertEquals(res2.getCode(), 902); // 获取信息2 - token = SaIdUtil.getTokenNh(); + token = SaSameUtil.getTokenNh(); // 加token,能调通 - SaResult res3 = request("/id/getInfo2", token); + SaResult res3 = request("/same/getInfo2", token); Assertions.assertEquals(res3.getCode(), 200); // 不加token,不能调通 - SaResult res4 = request("/id/getInfo2", "xxx"); + SaResult res4 = request("/same/getInfo2", "xxx"); Assertions.assertEquals(res4.getCode(), 902); } // 基础测试 @Test public void testApi() { - String token = SaIdUtil.getToken(); + String token = SaSameUtil.getToken(); // 刷新一下,会有变化 - SaIdUtil.refreshToken(); - String token2 = SaIdUtil.getToken(); + SaSameUtil.refreshToken(); + String token2 = SaSameUtil.getToken(); Assertions.assertNotEquals(token, token2); // 旧token,变为次级token - String pastToken = SaIdUtil.getPastTokenNh(); + String pastToken = SaSameUtil.getPastTokenNh(); Assertions.assertEquals(token, pastToken); // dao中应该有值 - String daoToken = SaManager.getSaTokenDao().get("satoken:var:id-token"); - String daoToken2 = SaManager.getSaTokenDao().get("satoken:var:past-id-token"); + String daoToken = SaManager.getSaTokenDao().get("satoken:var:same-token"); + String daoToken2 = SaManager.getSaTokenDao().get("satoken:var:past-same-token"); Assertions.assertEquals(token2, daoToken); Assertions.assertEquals(token, daoToken2); // 新旧都有效 - Assertions.assertTrue(SaIdUtil.isValid(token)); - Assertions.assertTrue(SaIdUtil.isValid(token2)); + Assertions.assertTrue(SaSameUtil.isValid(token)); + Assertions.assertTrue(SaSameUtil.isValid(token2)); // 空的不行 - Assertions.assertFalse(SaIdUtil.isValid(null)); - Assertions.assertFalse(SaIdUtil.isValid("")); + Assertions.assertFalse(SaSameUtil.isValid(null)); + Assertions.assertFalse(SaSameUtil.isValid("")); // 不抛出异常 - Assertions.assertDoesNotThrow(() -> SaIdUtil.checkToken(token)); - Assertions.assertDoesNotThrow(() -> SaIdUtil.checkToken(token2)); + Assertions.assertDoesNotThrow(() -> SaSameUtil.checkToken(token)); + Assertions.assertDoesNotThrow(() -> SaSameUtil.checkToken(token2)); // 抛出异常 - Assertions.assertThrows(IdTokenInvalidException.class, () -> SaIdUtil.checkToken(null)); - Assertions.assertThrows(IdTokenInvalidException.class, () -> SaIdUtil.checkToken("")); - Assertions.assertThrows(IdTokenInvalidException.class, () -> SaIdUtil.checkToken("aaa")); + Assertions.assertThrows(SameTokenInvalidException.class, () -> SaSameUtil.checkToken(null)); + Assertions.assertThrows(SameTokenInvalidException.class, () -> SaSameUtil.checkToken("")); + Assertions.assertThrows(SameTokenInvalidException.class, () -> SaSameUtil.checkToken("aaa")); } // 封装请求 - private SaResult request(String path, String idToken) { + private SaResult request(String path, String sameToken) { try { // 发请求 MvcResult mvcResult = mvc.perform( MockMvcRequestBuilders.post(path) .contentType(MediaType.APPLICATION_PROBLEM_JSON) .accept(MediaType.APPLICATION_PROBLEM_JSON) - .header(SaIdUtil.ID_TOKEN, idToken) + .header(SaSameUtil.SAME_TOKEN, sameToken) ) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn();