diff --git a/README.md b/README.md index 411594f0..f17bf5a8 100644 --- a/README.md +++ b/README.md @@ -127,9 +127,9 @@ StpUtil.switchTo(10044); // 将当前会话身份临时切换 | 系统架构 | 采用模式 | 简介 | 文档链接 | | :-------- | :-------- | :-------- | :-------- | -| 前端同域 + 后端同 Redis | 模式一 | 共享Cookie同步会话 | [文档](http://sa-token.dev33.cn/doc/index.html#/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso1-client) | -| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](http://sa-token.dev33.cn/doc/index.html#/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso2-client) | -| 前端不同域 + 后端 不同Redis | 模式三 | Http请求获取会话 | [文档](http://sa-token.dev33.cn/doc/index.html#/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso3-client) | +| 前端同域 + 后端同 Redis | 模式一 | 共享Cookie同步会话 | [文档](http://sa-token.dev33.cn/doc/index.html#/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso1-client) | +| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](http://sa-token.dev33.cn/doc/index.html#/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso2-client) | +| 前端不同域 + 后端 不同Redis | 模式三 | Http请求获取会话 | [文档](http://sa-token.dev33.cn/doc/index.html#/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso3-client) | 1. 前端同域:就是指多个系统可以部署在同一个主域名之下,比如:`c1.domain.com`、`c2.domain.com`、`c3.domain.com` 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 0b5bc781..d76af802 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 @@ -80,6 +80,8 @@ public class SaTokenConfig implements Serializable { /** 配置当前项目的网络访问地址 */ private String currDomain; + /** 是否校验Id-Token(部分rpc插件有效) */ + private Boolean checkIdToken = false; /** * Cookie配置对象 @@ -399,6 +401,22 @@ public class SaTokenConfig implements Serializable { this.currDomain = currDomain; return this; } + + /** + * @return 是否校验Id-Token(部分rpc插件有效) + */ + public Boolean getCheckIdToken() { + return checkIdToken; + } + + /** + * @param checkIdToken 是否校验Id-Token(部分rpc插件有效) + * @return 对象自身 + */ + public SaTokenConfig setCheckIdToken(Boolean checkIdToken) { + this.checkIdToken = checkIdToken; + return this; + } /** * @return SSO单点登录配置对象 @@ -454,6 +472,7 @@ public class SaTokenConfig implements Serializable { + ", idTokenTimeout=" + idTokenTimeout + ", basic=" + basic + ", currDomain=" + currDomain + + ", checkIdToken=" + checkIdToken + ", sso=" + sso + ", cookie=" + cookie + "]"; diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index d9437494..33312b0c 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -94,29 +94,52 @@ public class StpLogic { return SaStrategy.me.createToken.apply(loginId, loginType); } + /** + * 在当前会话写入当前TokenValue + * @param tokenValue token值 + */ + public void setTokenValue(String tokenValue){ + setTokenValue(tokenValue, (int)SaManager.getConfig().getTimeout()); + } + /** * 在当前会话写入当前TokenValue * @param tokenValue token值 * @param cookieTimeout Cookie存活时间(秒) */ public void setTokenValue(String tokenValue, int cookieTimeout){ - SaTokenConfig config = getConfig(); + if(SaFoxUtil.isEmpty(tokenValue)) { + return; + } + + // 1. 将token保存到[存储器]里 + setTokenValueToStorage(tokenValue); + + // 2. 将 Token 保存到 [Cookie] 里 + if (getConfig().getIsReadCookie()) { + setTokenValueToCookie(tokenValue, cookieTimeout); + } + } + + /** + * 将 Token 保存到 [Storage] 里 + * @param tokenValue token值 + */ + public void setTokenValueToStorage(String tokenValue){ // 1. 将token保存到[存储器]里 SaStorage storage = SaHolder.getStorage(); - // 如果打开了token前缀模式,则拼接上前缀一起写入 - String tokenPrefix = config.getTokenPrefix(); + // 2. 如果打开了 Token 前缀模式,则拼接上前缀 + String tokenPrefix = getConfig().getTokenPrefix(); if(SaFoxUtil.isEmpty(tokenPrefix) == false) { storage.set(splicingKeyJustCreatedSave(), tokenPrefix + SaTokenConsts.TOKEN_CONNECTOR_CHAT + tokenValue); } else { storage.set(splicingKeyJustCreatedSave(), tokenValue); } - // 2. 将 Token 保存到 [Cookie] 里 - if (config.getIsReadCookie()) { - setTokenValueToCookie(tokenValue, cookieTimeout); - } + // 3. 写入 (无前缀) + storage.set(SaTokenConsts.JUST_CREATED_NOT_PREFIX, tokenValue); } /** @@ -144,6 +167,30 @@ public class StpLogic { * @return 当前tokenValue */ public String getTokenValue(){ + // 1. 获取 + String tokenValue = getTokenValueNotCut(); + + // 2. 如果打开了前缀模式,则裁剪掉 + String tokenPrefix = getConfig().getTokenPrefix(); + if(SaFoxUtil.isEmpty(tokenPrefix) == false) { + // 如果token并没有按照指定的前缀开头,则视为未提供token + if(SaFoxUtil.isEmpty(tokenValue) || tokenValue.startsWith(tokenPrefix + SaTokenConsts.TOKEN_CONNECTOR_CHAT) == false) { + tokenValue = null; + } else { + // 则裁剪掉前缀 + tokenValue = tokenValue.substring(tokenPrefix.length() + SaTokenConsts.TOKEN_CONNECTOR_CHAT.length()); + } + } + + // 3. 返回 + return tokenValue; + } + + /** + * 获取当前TokenValue (不裁剪前缀) + * @return / + */ + public String getTokenValueNotCut(){ // 0. 获取相应对象 SaStorage storage = SaHolder.getStorage(); SaRequest request = SaHolder.getRequest(); @@ -168,19 +215,7 @@ public class StpLogic { tokenValue = request.getCookieValue(keyTokenName); } - // 5. 如果打开了前缀模式 - String tokenPrefix = getConfig().getTokenPrefix(); - if(SaFoxUtil.isEmpty(tokenPrefix) == false) { - // 如果token并没有按照指定的前缀开头,则视为未提供token - if(SaFoxUtil.isEmpty(tokenValue) || tokenValue.startsWith(tokenPrefix + SaTokenConsts.TOKEN_CONNECTOR_CHAT) == false) { - tokenValue = null; - } else { - // 则裁剪掉前缀 - tokenValue = tokenValue.substring(tokenPrefix.length() + SaTokenConsts.TOKEN_CONNECTOR_CHAT.length()); - } - } - - // 6. 返回 + // 5. 返回 return tokenValue; } @@ -1599,7 +1634,8 @@ public class StpLogic { * @return key */ public String splicingKeyJustCreatedSave() { - return SaTokenConsts.JUST_CREATED_SAVE_KEY + loginType; +// return SaTokenConsts.JUST_CREATED_SAVE_KEY + loginType; + return SaTokenConsts.JUST_CREATED; } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java index f6b858e1..2f46bc22 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java @@ -51,6 +51,14 @@ public class StpUtil { return stpLogic.getTokenName(); } + /** + * 在当前会话写入当前TokenValue + * @param tokenValue token值 + */ + public static void setTokenValue(String tokenValue){ + stpLogic.setTokenValue(tokenValue); + } + /** * 在当前会话写入当前TokenValue * @param tokenValue token值 @@ -68,6 +76,14 @@ public class StpUtil { return stpLogic.getTokenValue(); } + /** + * 获取当前TokenValue (不裁剪前缀) + * @return / + */ + public static String getTokenValueNotCut(){ + return stpLogic.getTokenValueNotCut(); + } + /** * 获取当前会话的Token信息 * @return token信息 diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java index b5414d84..d97e9c48 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java @@ -30,7 +30,12 @@ public class SaTokenConsts { /** * 常量key标记: 如果token为本次请求新创建的,则以此字符串为key存储在当前request中 */ - public static final String JUST_CREATED_SAVE_KEY = "JUST_CREATED_SAVE_KEY_"; + public static final String JUST_CREATED = "JUST_CREATED_"; + + /** + * 常量key标记: 如果token为本次请求新创建的,则以此字符串为key存储在当前request中(不拼接前缀,纯Token) + */ + public static final String JUST_CREATED_NOT_PREFIX = "JUST_CREATED_NOT_PREFIX_"; /** * 常量key标记: 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中 @@ -97,5 +102,14 @@ public class SaTokenConsts { * 切面、拦截器、过滤器等各种组件的注册优先级顺序 */ public static final int ASSEMBLY_ORDER = -100; + + + // =================== 废弃 =================== + + /** + * 请更换为 JUST_CREATED + */ + @Deprecated + public static final String JUST_CREATED_SAVE_KEY = JUST_CREATED; } diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/.gitignore b/sa-token-demo/sa-token-demo-dubbo-consumer/.gitignore new file mode 100644 index 00000000..304e8d54 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/.gitignore @@ -0,0 +1,13 @@ +target/ +.project +.classpath +.settings + +/.idea/ + +node_modules/ +bin/ +.settings/ +unpackage/ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml b/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml new file mode 100644 index 00000000..d28de1a8 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml @@ -0,0 +1,75 @@ + + 4.0.0 + com.pj + sa-token-demo-dubbo-consumer + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + + + + 1.8 + 3.1.1 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + cn.dev33 + sa-token-spring-boot-starter + 1.27.0 + + + + + cn.dev33 + sa-token-dao-redis-jackson + 1.27.0 + + + org.apache.commons + commons-pool2 + + + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.11 + + + + + org.apache.dubbo + dubbo-registry-nacos + 2.7.11 + + + com.alibaba.nacos + nacos-client + 1.4.1 + + + + + cn.dev33 + sa-token-context-dubbo + 1.27.0 + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/ConsumerApplication.java b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/ConsumerApplication.java new file mode 100644 index 00000000..1936b0d5 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/ConsumerApplication.java @@ -0,0 +1,22 @@ +package com.pj; + +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Dubbo 服务消费端 + * + * @author kong + * + */ +@EnableDubbo +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + System.out.println("ConsumerApplication 启动成功"); + } + +} diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/more/DemoService.java b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/more/DemoService.java new file mode 100644 index 00000000..392a2ead --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/more/DemoService.java @@ -0,0 +1,16 @@ +package com.pj.more; + +public interface DemoService { + + /** + * 登录 + * @param loginId 账号id + */ + void doLogin(Object loginId); + + /** + * 判断是否登录,打印状态 + */ + void isLogin(String str); + +} diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/more/TestController.java b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/more/TestController.java new file mode 100644 index 00000000..d933e121 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/java/com/pj/more/TestController.java @@ -0,0 +1,60 @@ +package com.pj.more; + +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.dev33.satoken.stp.StpUtil; + +@RestController +public class TestController { + + @DubboReference + private DemoService demoService; + + // Consumer端登录,状态传播到Provider端 + @RequestMapping("test") + public String test() { + demoService.isLogin("----------- 登录前 "); + + StpUtil.login(10001); + + demoService.isLogin("----------- 登录后 "); + + return "ok"; + } + + // Provider端登录,状态回传到Consumer端 + @RequestMapping("test2") + public String test2() { + System.out.println("----------- 登录前 "); + System.out.println("Token值:" + StpUtil.getTokenValue()); + System.out.println("是否登录:" + StpUtil.isLogin()); + + demoService.doLogin(10002); + + System.out.println("----------- 登录后 "); + System.out.println("Token值:" + StpUtil.getTokenValue()); + System.out.println("是否登录:" + StpUtil.isLogin()); + + return "ok"; + } + + // Consumer端登录,状态在Consumer端保持 + @RequestMapping("test3") + public String test3() { + System.out.println("----------- 登录前 "); + System.out.println("Token值:" + StpUtil.getTokenValue()); + System.out.println("是否登录:" + StpUtil.isLogin()); + + StpUtil.login(10003); + demoService.isLogin("----------- Provider状态"); + + System.out.println("----------- 登录后 "); + System.out.println("Token值:" + StpUtil.getTokenValue()); + System.out.println("是否登录:" + StpUtil.isLogin()); + + return "ok"; + } + +} \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/resources/application.yml new file mode 100644 index 00000000..a877a366 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/src/main/resources/application.yml @@ -0,0 +1,24 @@ +server: + # 端口号 + port: 8081 + +spring: + # redis配置 + redis: + # Redis数据库索引(默认为0) + database: 0 + # Redis服务器地址 + host: 127.0.0.1 + # Redis服务器连接端口 + port: 6379 + # Redis服务器连接密码(默认为空) + password: + # 连接超时时间 + +dubbo: + application: + # 服务名称 + name: dubbo-consumer-demo + registry: + # 注册中心地址 + address: nacos://127.0.0.1:8001 diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/.gitignore b/sa-token-demo/sa-token-demo-dubbo-provider/.gitignore new file mode 100644 index 00000000..304e8d54 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-provider/.gitignore @@ -0,0 +1,13 @@ +target/ +.project +.classpath +.settings + +/.idea/ + +node_modules/ +bin/ +.settings/ +unpackage/ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml b/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml new file mode 100644 index 00000000..947a284d --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml @@ -0,0 +1,75 @@ + + 4.0.0 + com.pj + sa-token-demo-dubbo-provider + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + + + + 1.8 + 3.1.1 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + cn.dev33 + sa-token-spring-boot-starter + 1.27.0 + + + + + cn.dev33 + sa-token-dao-redis-jackson + 1.27.0 + + + org.apache.commons + commons-pool2 + + + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.11 + + + + + org.apache.dubbo + dubbo-registry-nacos + 2.7.11 + + + com.alibaba.nacos + nacos-client + 1.4.1 + + + + + cn.dev33 + sa-token-context-dubbo + 1.27.0 + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/ProviderApplication.java b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/ProviderApplication.java new file mode 100644 index 00000000..8eb9567c --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/ProviderApplication.java @@ -0,0 +1,22 @@ +package com.pj; + +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Dubbo 服务提供端 + * + * @author kong + * + */ +@EnableDubbo +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class, args); + System.out.println("ProviderApplication 启动成功"); + } + +} diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/more/DemoService.java b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/more/DemoService.java new file mode 100644 index 00000000..392a2ead --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/more/DemoService.java @@ -0,0 +1,16 @@ +package com.pj.more; + +public interface DemoService { + + /** + * 登录 + * @param loginId 账号id + */ + void doLogin(Object loginId); + + /** + * 判断是否登录,打印状态 + */ + void isLogin(String str); + +} diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/more/DemoServiceImpl.java b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/more/DemoServiceImpl.java new file mode 100644 index 00000000..8cfe559c --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/java/com/pj/more/DemoServiceImpl.java @@ -0,0 +1,23 @@ +package com.pj.more; + +import org.apache.dubbo.config.annotation.DubboService; + +import cn.dev33.satoken.stp.StpUtil; + +@DubboService() +public class DemoServiceImpl implements DemoService { + + @Override + public void doLogin(Object loginId) { + StpUtil.login(loginId); + } + + @Override + public void isLogin(String str) { + System.out.println(str); + System.out.println("Token值:" + StpUtil.getTokenValue()); + System.out.println("是否登录:" + StpUtil.isLogin()); + } + +} + diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/resources/application.yml new file mode 100644 index 00000000..1aac2ea7 --- /dev/null +++ b/sa-token-demo/sa-token-demo-dubbo-provider/src/main/resources/application.yml @@ -0,0 +1,38 @@ +server: + # 端口号 + port: 8080 + +spring: + # redis配置 + redis: + # Redis数据库索引(默认为0) + database: 0 + # Redis服务器地址 + host: 127.0.0.1 + # Redis服务器连接端口 + port: 6379 + # Redis服务器连接密码(默认为空) + password: + # 连接超时时间 + timeout: 10s + +# Dubbo +dubbo: + # 服务名 + application: + name: dubbo-provider-demo + # 扫描包 + scan: + base-packages: com.pj + # 注册中心地址 + registry: + address: nacos://127.0.0.1:8001 + # 协议 + protocol: + name: dubbo + port: 12345 + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/at/StpUserUtil.java b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/at/StpUserUtil.java index 4e112f00..a0fa0767 100644 --- a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/at/StpUserUtil.java +++ b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/at/StpUserUtil.java @@ -2,8 +2,6 @@ package com.pj.satoken.at; import java.util.List; -import org.springframework.stereotype.Component; - import cn.dev33.satoken.SaManager; import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.session.SaSession; @@ -13,10 +11,9 @@ import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; /** - * Sa-Token 权限认证工具类 + * Sa-Token 权限认证工具类 (User版) * @author kong */ -@Component public class StpUserUtil { /** @@ -58,6 +55,14 @@ public class StpUserUtil { return stpLogic.getTokenName(); } + /** + * 在当前会话写入当前TokenValue + * @param tokenValue token值 + */ + public static void setTokenValue(String tokenValue){ + stpLogic.setTokenValue(tokenValue); + } + /** * 在当前会话写入当前TokenValue * @param tokenValue token值 @@ -75,6 +80,14 @@ public class StpUserUtil { return stpLogic.getTokenValue(); } + /** + * 获取当前TokenValue (不裁剪前缀) + * @return / + */ + public static String getTokenValueNotCut(){ + return stpLogic.getTokenValueNotCut(); + } + /** * 获取当前会话的Token信息 * @return token信息 @@ -347,7 +360,7 @@ public class StpUserUtil { } - // =================== [临时过期] 验证相关 =================== + // =================== [临时有效期] 验证相关 =================== /** * 检查当前token 是否已经[临时过期],如果已经过期则抛出异常 @@ -404,8 +417,34 @@ public class StpUserUtil { // =================== 角色验证操作 =================== + /** + * 获取:当前账号的角色集合 + * @return / + */ + public static List getRoleList() { + return stpLogic.getRoleList(); + } + + /** + * 获取:指定账号的角色集合 + * @param loginId 指定账号id + * @return / + */ + public static List getRoleList(Object loginId) { + return stpLogic.getRoleList(loginId); + } + /** - * 判断:指定账号id是否含有角色标识, 返回true或false + * 判断:当前账号是否拥有指定角色, 返回true或false + * @param role 角色标识 + * @return 是否含有指定角色标识 + */ + public static boolean hasRole(String role) { + return stpLogic.hasRole(role); + } + + /** + * 判断:指定账号是否含有指定角色标识, 返回true或false * @param loginId 账号id * @param role 角色标识 * @return 是否含有指定角色标识 @@ -414,15 +453,6 @@ public class StpUserUtil { return stpLogic.hasRole(loginId, role); } - /** - * 判断:当前账号是否含有指定角色标识, 返回true或false - * @param role 角色标识 - * @return 是否含有指定角色标识 - */ - public static boolean hasRole(String role) { - return stpLogic.hasRole(role); - } - /** * 判断:当前账号是否含有指定角色标识 [指定多个,必须全部验证通过] * @param roleArray 角色标识数组 @@ -465,26 +495,24 @@ public class StpUserUtil { stpLogic.checkRoleOr(roleArray); } - // -- - /** - * 返回当前账号所拥有的角色标识集合 - * @return / - */ - public static List getRoleList() { - return stpLogic.getRoleList(); - } - // =================== 权限验证操作 =================== - /** - * 判断:指定账号id是否含有指定权限, 返回true或false - * @param loginId 账号id - * @param permission 权限码 - * @return 是否含有指定权限 - */ - public static boolean hasPermission(Object loginId, String permission) { - return stpLogic.hasPermission(loginId, permission); + /** + * 获取:当前账号的权限码集合 + * @return / + */ + public static List getPermissionList() { + return stpLogic.getPermissionList(); + } + + /** + * 获取:指定账号的权限码集合 + * @param loginId 指定账号id + * @return / + */ + public static List getPermissionList(Object loginId) { + return stpLogic.getPermissionList(loginId); } /** @@ -496,6 +524,16 @@ public class StpUserUtil { return stpLogic.hasPermission(permission); } + /** + * 判断:指定账号id是否含有指定权限, 返回true或false + * @param loginId 账号id + * @param permission 权限码 + * @return 是否含有指定权限 + */ + public static boolean hasPermission(Object loginId, String permission) { + return stpLogic.hasPermission(loginId, permission); + } + /** * 判断:当前账号是否含有指定权限, [指定多个,必须全部具有] * @param permissionArray 权限码数组 @@ -538,15 +576,6 @@ public class StpUserUtil { stpLogic.checkPermissionOr(permissionArray); } - // -- - /** - * 返回当前账号所拥有的权限码集合 - * @return / - */ - public static List getPermissionList() { - return stpLogic.getPermissionList(); - } - // =================== id 反查token 相关操作 =================== @@ -819,6 +848,7 @@ public class StpUserUtil { *

当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2 * @param loginId 账号id */ + @Deprecated public static void logoutByLoginId(Object loginId) { stpLogic.kickout(loginId); } @@ -831,6 +861,7 @@ public class StpUserUtil { * @param loginId 账号id * @param device 设备标识 (填null代表所有注销设备) */ + @Deprecated public static void logoutByLoginId(Object loginId, String device) { stpLogic.kickout(loginId, device); } diff --git a/sa-token-doc/doc/_sidebar.md b/sa-token-doc/doc/_sidebar.md index cf267936..d3ee2e71 100644 --- a/sa-token-doc/doc/_sidebar.md +++ b/sa-token-doc/doc/_sidebar.md @@ -65,6 +65,7 @@ - [持久层扩展](/plugin/dao-extend) - [和 Thymeleaf 集成](/plugin/thymeleaf-extend) - [和 jwt 集成](/plugin/jwt-extend) + - [和 Dubbo 集成](/plugin/dubbo-extend) - **其它** - [更新日志](/more/update-log) diff --git a/sa-token-doc/doc/more/sa-token-donate.md b/sa-token-doc/doc/more/sa-token-donate.md index 9e434118..7fc74692 100644 --- a/sa-token-doc/doc/more/sa-token-donate.md +++ b/sa-token-doc/doc/more/sa-token-donate.md @@ -19,6 +19,9 @@ Sa-Token 采用 Apache-2.0 开源协议,**承诺框架本身与官网文档永 | 赞助人 | 赞助金额 | 留言 | 时间 | | :-------- | :-------- | :-------- | :-------- | +| songfazhun | ¥ 10 | 感谢您的开源项目! | 2021-10-28 | +| ithorns | ¥ 10 | 感谢您的开源项目! | 2021-10-25 | +| xiaoyan | ¥ 200 | 节日快乐 | 2021-10-24 | | apifox001 | ¥ 200 | 开源不易,Apifox(apifox.cn)和你们一起加油! | 2021-10-15 | | 永夜 | ¥ 20 | 感谢您的开源项目! | 2021-09-18 | | 苏永晓 | ¥ 10 | 感谢您的开源项目! | 2021-09-01 | diff --git a/sa-token-doc/doc/plugin/dubbo-extend.md b/sa-token-doc/doc/plugin/dubbo-extend.md new file mode 100644 index 00000000..c5bfad89 --- /dev/null +++ b/sa-token-doc/doc/plugin/dubbo-extend.md @@ -0,0 +1,148 @@ +# 和 Dubbo 集成 + +本插件的作用是让 Sa-Token 和 Dubbo 做一个整合。 + +--- + +### 先说说要解决的问题 + +在 Dubbo 的整个调用链中,代码被分为 Consumer 端和 Provider 端,为方便理解我们可以称其为 `[调用端]` 和 `[被调用端]`。 + +RPC 模式的调用,可以让我们像调用本地方法一样完成服务通信,然而这种便利下却隐藏着两个问题: + +- 上下文环境的丢失。 +- 上下文参数的丢失。 + +这种问题作用在 Sa-Token 框架上就是,在 [ 被调用端 ] 调用 Sa-Token 相关API会抛出异常:**`无效上下文`**。 + +所以本插件的目的也就是解决上述两个问题: + +- 在 [ 被调用端 ] 提供以 Dubbo 为基础的上下文环境 +- 在 RPC 调用时将 Token 传递至 [ 被调用端 ],同时在调用结束时将 Token 回传至 [ 调用端 ]。 + + +### 引入插件 + +在项目已经引入 Dubbo 的基础上,继续添加依赖(Consumer 端和 Provider 端都需要引入): + +``` xml + + + cn.dev33 + sa-token-context-dubbo + ${sa.top.version} + +``` + + +然后我们就可以愉快的做到以下事情: + +1. 在 [ 被调用端 ] 安全的调用 Sa-Token 相关 API。 +2. 在 [ 调用端 ] 登录的会话,其登录状态可以自动传递到 [ 被调用端 ] 。 +3. 在 [ 被调用端 ] 登录的会话,其登录状态也会自动回传到 [ 调用端 ] 。 + +但是我们仍具有以下限制: + +1. [ 调用端 ] 与 [ 被调用端 ] 的 `SaStorage` 数据无法互通。 +2. [ 被调用端 ] 执行的 `SaResponse.setHeader()`、`setStatus()` 等代码无效。 + +应该合理避开以上 API 的使用。 + + +### RPC调用鉴权 + +在之前的 [Id-Token](/micro/id-token) 章节,我们演示了基于 Feign 的 RPC 调用鉴权,下面我们演示一下在 Dubbo 中如何集成 Id-Token 模块。 + +其实思路和 Feign 模式一致,在 [ 调用端 ] 追加 Id-Token 参数,在 [ 被调用端 ] 校验这个 Id-Token 参数: + +- 校验通过:调用成功。 +- 校验不通过:通过失败,抛出异常。 + +我们有两种方式完成整合。 + +##### 方式一、使用配置 + +直接在 `application.yml` 配置即可: + +``` yml +sa-token: + # 打开 RPC 调用鉴权 + check-id-token: true +``` + + +##### 方式二、自建 Dubbo 过滤器校验 + +1、在 [ 调用端 ] 的 `\resources\META-INF\dubbo\` 目录新建 `org.apache.dubbo.rpc.Filter` 文件 +``` html +dubboConsumerFilter=com.pj.DubboConsumerFilter +``` + +新建 `DubboConsumerFilter.java` 过滤器 + +``` java +package com.pj; + +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; + +/** + * Sa-Token 整合 Dubbo Consumer端过滤器 + */ +@Activate(group = {CommonConstants.CONSUMER}, order = -10000) +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()); + + // 开始调用 + return invoker.invoke(invocation); + } + +} +``` + + +2、在 [ 被调用端 ] 的 `\resources\META-INF\dubbo\` 目录新建 `org.apache.dubbo.rpc.Filter` 文件 +``` html +dubboProviderFilter=com.pj.DubboProviderFilter +``` + +新建 `DubboProviderFilter.java` 过滤器 + +``` java +package com.pj; + +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; + +/** + * Sa-Token 整合 Dubbo Provider端过滤器 + */ +@Activate(group = {CommonConstants.PROVIDER}, order = -10000) +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); + + // 开始调用 + return invoker.invoke(invocation); + } + +} +``` + +然后我们就可以进行安全的 RPC 调用了,不带有 Id-Token 参数的调用都会抛出异常,无法调用成功。 diff --git a/sa-token-doc/doc/sso/readme.md b/sa-token-doc/doc/sso/readme.md index a5111a1c..3a9a3568 100644 --- a/sa-token-doc/doc/sso/readme.md +++ b/sa-token-doc/doc/sso/readme.md @@ -19,9 +19,9 @@ | 系统架构 | 采用模式 | 简介 | 文档链接 | | :-------- | :-------- | :-------- | :-------- | -| 前端同域 + 后端同 Redis | 模式一 | 共享 Cookie 同步会话 | [文档](/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso1-client) | -| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso2-client) | -| 前端不同域 + 后端不同 Redis | 模式三 | Http请求获取会话 | [文档](/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso3-client) | +| 前端同域 + 后端同 Redis | 模式一 | 共享 Cookie 同步会话 | [文档](/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso1-client) | +| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso2-client) | +| 前端不同域 + 后端不同 Redis | 模式三 | Http请求获取会话 | [文档](/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-sso3-client) | 1. 前端同域:就是指多个系统可以部署在同一个主域名之下,比如:`c1.domain.com`、`c2.domain.com`、`c3.domain.com`。 diff --git a/sa-token-doc/doc/use/config.md b/sa-token-doc/doc/use/config.md index 42694d62..93e8a678 100644 --- a/sa-token-doc/doc/use/config.md +++ b/sa-token-doc/doc/use/config.md @@ -94,7 +94,8 @@ PS:两者的区别在于:**`模式1会覆盖yml中的配置,模式2会与y | jwtSecretKey | String | null | jwt秘钥 (只有集成 `sa-token-temp-jwt` 模块时此参数才会生效) | | idTokenTimeout | long | 86400 | Id-Token的有效期 (单位: 秒) | | basic | String | "" | Http Basic 认证的账号和密码 [参考:Http Basic 认证](/up/basic-auth) | -| currDomain | null | "" | 配置当前项目的网络访问地址 | +| currDomain | Boolean | false | 是否校验Id-Token(部分rpc插件有效) | +| checkIdToken | false | false | 配置当前项目的网络访问地址 | | sso | Object | new SaSsoConfig() | SSO 单点登录相关配置 | | cookie | Object | new SaCookieConfig() | Cookie配置对象 | diff --git a/sa-token-doc/index.html b/sa-token-doc/index.html index 3d986a4e..b701d0fb 100644 --- a/sa-token-doc/index.html +++ b/sa-token-doc/index.html @@ -311,7 +311,7 @@ - + @@ -442,6 +442,42 @@ content: content }); }) + + // set 一下 img 的宽度 + function setImgWidth(img) { + // 如果已经有了宽度参数,则不追加 + if(img.src.indexOf('?') > -1) { + return; + } + // console.log(img.getAttribute('nf')); + if(img.getAttribute('nf') != null) { + return; + } + img.src = img.src + "?x-oss-process=image/resize,m_lfit,w_" + (img.width) + ",limit_0/auto-orient,0"; + } + + // set 一遍 img 的尺寸,防止失真 + function f5ImgSize() { + $('.com-box-f .com-box a img').each(function() { + // console.log(this.src, this.width); + // 未加载完毕时,则等待其load之后再设置 + if(this.complete == false) { + this.onload = function() { + setImgWidth(this); + } + return; + } + // 追加宽度参数 + setImgWidth(this); + }) + } + if(window.innerWidth > 1800) { + if(navigator.userAgent.indexOf('WebKit') > -1) { + f5ImgSize(); + } + } + + diff --git a/sa-token-plugin/pom.xml b/sa-token-plugin/pom.xml index 580608b1..0d15b636 100644 --- a/sa-token-plugin/pom.xml +++ b/sa-token-plugin/pom.xml @@ -26,6 +26,7 @@ sa-token-spring-aop sa-token-temp-jwt sa-token-jwt + sa-token-context-dubbo diff --git a/sa-token-plugin/sa-token-context-dubbo/.gitignore b/sa-token-plugin/sa-token-context-dubbo/.gitignore new file mode 100644 index 00000000..f56feec7 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.factorypath + +.idea/ \ No newline at end of file diff --git a/sa-token-plugin/sa-token-context-dubbo/pom.xml b/sa-token-plugin/sa-token-context-dubbo/pom.xml new file mode 100644 index 00000000..6d60c9a6 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + + cn.dev33 + sa-token-plugin + 1.27.0 + + jar + + sa-token-context-dubbo + sa-token-context-dubbo + sa-token-context-dubbo + + + + + cn.dev33 + sa-token-core + ${sa-token-version} + + + + + org.apache.dubbo + dubbo + 2.7.11 + + + + + + + diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/SaTokenSecondContextCreatorForDubbo.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/SaTokenSecondContextCreatorForDubbo.java new file mode 100644 index 00000000..7c2ca61b --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/SaTokenSecondContextCreatorForDubbo.java @@ -0,0 +1,19 @@ +package cn.dev33.satoken.context.dubbo; + +import cn.dev33.satoken.context.second.SaTokenSecondContext; +import cn.dev33.satoken.context.second.SaTokenSecondContextCreator; + +/** + * Sa-Token 二级Context - 创建器 [Dubbo版] + * + * @author kong + * + */ +public class SaTokenSecondContextCreatorForDubbo implements SaTokenSecondContextCreator { + + @Override + public SaTokenSecondContext create() { + return new SaTokenSecondContextForDubbo(); + } + +} diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/SaTokenSecondContextForDubbo.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/SaTokenSecondContextForDubbo.java new file mode 100644 index 00000000..5d4a10af --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/SaTokenSecondContextForDubbo.java @@ -0,0 +1,47 @@ +package cn.dev33.satoken.context.dubbo; + +import org.apache.dubbo.rpc.RpcContext; + +import cn.dev33.satoken.context.dubbo.model.SaRequestForDubbo; +import cn.dev33.satoken.context.dubbo.model.SaResponseForDubbo; +import cn.dev33.satoken.context.dubbo.model.SaStorageForDubbo; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.context.model.SaStorage; +import cn.dev33.satoken.context.second.SaTokenSecondContext; +import cn.dev33.satoken.exception.ApiDisabledException; + +/** + * Sa-Token 上下文 [Dubbo版本] + * + * @author kong + * + */ +public class SaTokenSecondContextForDubbo implements SaTokenSecondContext { + + @Override + public SaRequest getRequest() { + return new SaRequestForDubbo(RpcContext.getContext()); + } + + @Override + public SaResponse getResponse() { + return new SaResponseForDubbo(RpcContext.getContext()); + } + + @Override + public SaStorage getStorage() { + return new SaStorageForDubbo(RpcContext.getContext()); + } + + @Override + public boolean matchPath(String pattern, String path) { + throw new ApiDisabledException(); + } + + @Override + public boolean isValid() { + return RpcContext.getContext() != null; + } + +} 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 new file mode 100644 index 00000000..451c9f3a --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboConsumerFilter.java @@ -0,0 +1,48 @@ +package cn.dev33.satoken.context.dubbo.filter; + +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcException; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.id.SaIdUtil; +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaTokenConsts; + +/** + * + * Sa-Token 整合 Dubbo Consumer端过滤器 + * + * @author kong + * + */ +@Activate(group = {CommonConstants.CONSUMER}, order = -10000) +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()); + } + + // 1. 调用前,向下传递会话Token + RpcContext.getContext().setAttachment(SaTokenConsts.JUST_CREATED, StpUtil.getTokenValueNotCut()); + + // 2. 开始调用 + Result invoke = invoker.invoke(invocation); + + // 3. 调用后,解析回传的Token值 + StpUtil.setTokenValue(invoke.getAttachment(SaTokenConsts.JUST_CREATED_NOT_PREFIX)); + + // note + return invoke; + } + +} 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 new file mode 100644 index 00000000..03ffca81 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/filter/SaTokenDubboProviderFilter.java @@ -0,0 +1,37 @@ +package cn.dev33.satoken.context.dubbo.filter; + +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.id.SaIdUtil; + +/** + * + * Sa-Token 整合 Dubbo Provider端过滤器 + * + * @author kong + * + */ +@Activate(group = {CommonConstants.PROVIDER}, order = -10000) +public class SaTokenDubboProviderFilter implements Filter { + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + + // RPC 调用鉴权 + if(SaManager.getConfig().getCheckIdToken()) { + String idToken = invocation.getAttachment(SaIdUtil.ID_TOKEN); + SaIdUtil.checkToken(idToken); + } + + // 开始调用 + return invoker.invoke(invocation); + } + +} diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaRequestForDubbo.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaRequestForDubbo.java new file mode 100644 index 00000000..3e506528 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaRequestForDubbo.java @@ -0,0 +1,99 @@ +package cn.dev33.satoken.context.dubbo.model; + +import org.apache.dubbo.rpc.RpcContext; + +import cn.dev33.satoken.context.model.SaRequest; + +/** + * Request for Dubbo + * + * @author kong + * + */ +public class SaRequestForDubbo implements SaRequest { + + /** + * 底层对象 + */ + protected RpcContext rpcContext; + + /** + * 实例化 + * @param rpcContext rpcContext对象 + */ + public SaRequestForDubbo(RpcContext rpcContext) { + this.rpcContext = rpcContext; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return rpcContext; + } + + /** + * 在 [请求体] 里获取一个值 + */ + @Override + public String getParam(String name) { + // 不传播 url 参数 + return null; + } + + /** + * 在 [请求头] 里获取一个值 + */ + @Override + public String getHeader(String name) { + // 不传播 header 参数 + return null; + } + + /** + * 在 [Cookie作用域] 里获取一个值 + */ + @Override + public String getCookieValue(String name) { + // 不传播 cookie 参数 + return null; + } + + /** + * 返回当前请求path (不包括上下文名称) + */ + @Override + public String getRequestPath() { + // 不传播 requestPath + return null; + } + + /** + * 返回当前请求的url,例:http://xxx.com/test + * @return see note + */ + public String getUrl() { + // 不传播 url + return null; + } + + /** + * 返回当前请求的类型 + */ + @Override + public String getMethod() { + // 不传播 method + return null; + } + + /** + * 转发请求 + */ + @Override + public Object forward(String path) { + // 不传播 forward 动作 + return null; + } + +} diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaResponseForDubbo.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaResponseForDubbo.java new file mode 100644 index 00000000..fc28ffe6 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaResponseForDubbo.java @@ -0,0 +1,74 @@ +package cn.dev33.satoken.context.dubbo.model; + +import org.apache.dubbo.rpc.RpcContext; + +import cn.dev33.satoken.context.model.SaResponse; + +/** + * Response for Servlet + * @author kong + * + */ +public class SaResponseForDubbo implements SaResponse { + + /** + * 底层Request对象 + */ + protected RpcContext rpcContext; + + /** + * 实例化 + * @param rpcContext rpcContext对象 + */ + public SaResponseForDubbo(RpcContext rpcContext) { + this.rpcContext = rpcContext; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return rpcContext; + } + + /** + * 设置响应状态码 + */ + @Override + public SaResponse setStatus(int sc) { + // 不回传 status 状态 + return this; + } + + /** + * 在响应头里写入一个值 + */ + @Override + public SaResponse setHeader(String name, String value) { + // 不回传 header响应头 + return this; + } + + /** + * 在响应头里添加一个值 + * @param name 名字 + * @param value 值 + * @return 对象自身 + */ + public SaResponse addHeader(String name, String value) { + // 不回传 header响应头 + return this; + } + + /** + * 重定向 + */ + @Override + public Object redirect(String url) { + // 不回传 重定向 动作 + return null; + } + + +} diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaStorageForDubbo.java b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaStorageForDubbo.java new file mode 100644 index 00000000..6311d7ed --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/java/cn/dev33/satoken/context/dubbo/model/SaStorageForDubbo.java @@ -0,0 +1,64 @@ +package cn.dev33.satoken.context.dubbo.model; + +import org.apache.dubbo.rpc.RpcContext; + +import cn.dev33.satoken.context.model.SaStorage; +import cn.dev33.satoken.util.SaTokenConsts; + +/** + * Storage for Servlet + * @author kong + * + */ +public class SaStorageForDubbo implements SaStorage { + + /** + * 底层对象 + */ + protected RpcContext rpcContext; + + /** + * 实例化 + * @param rpcContext rpcContext对象 + */ + public SaStorageForDubbo(RpcContext rpcContext) { + this.rpcContext = rpcContext; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return rpcContext; + } + + /** + * 在 [Request作用域] 里写入一个值 + */ + @Override + public void set(String key, Object value) { + rpcContext.setObjectAttachment(key, value); + // 如果是token写入,则回传到Consumer端 + if(key.equals(SaTokenConsts.JUST_CREATED_NOT_PREFIX)) { + RpcContext.getServerContext().setAttachment(key, value); + } + } + + /** + * 在 [Request作用域] 里获取一个值 + */ + @Override + public Object get(String key) { + return rpcContext.getObjectAttachment(key); + } + + /** + * 在 [Request作用域] 里删除一个值 + */ + @Override + public void delete(String key) { + rpcContext.removeAttachment(key); + } + +} diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter b/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter new file mode 100644 index 00000000..c7b1d87e --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter @@ -0,0 +1,2 @@ +saTokenDubboConsumerFilter=cn.dev33.satoken.context.dubbo.filter.SaTokenDubboConsumerFilter +saTokenDubboProviderFilter=cn.dev33.satoken.context.dubbo.filter.SaTokenDubboProviderFilter \ No newline at end of file diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring.factories b/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..dfd24ad8 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.context.dubbo.SaTokenSecondContextCreatorForDubbo \ No newline at end of file