From cfd7a71ca32b3db11a85a84154ae2ea343c77f22 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Wed, 26 Oct 2022 11:42:19 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84SSO=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E9=9D=99=E6=80=81=E5=BC=8FAPI=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/pj/sso/SsoServerController.java | 6 +- ...tion.java => SaSso1ClientApplication.java} | 4 +- .../src/main/resources/application.yml | 2 +- ...tion.java => SaSso2ClientApplication.java} | 4 +- .../src/main/java/com/pj/h5/H5Controller.java | 4 +- .../java/com/pj/sso/SsoClientController.java | 4 +- ...tion.java => SaSso3ClientApplication.java} | 4 +- .../java/com/pj/sso/SsoClientController.java | 4 +- .../src/main/resources/application.yml | 2 +- sa-token-doc/sso/sso-apidoc.md | 6 +- sa-token-doc/sso/sso-custom-api.md | 21 +- sa-token-doc/sso/sso-h5.md | 2 +- sa-token-doc/sso/sso-home-jump.md | 2 +- sa-token-doc/sso/sso-server.md | 2 +- sa-token-doc/sso/sso-type1.md | 8 +- sa-token-doc/sso/sso-type2.md | 6 +- sa-token-doc/sso/sso-type3.md | 4 +- sa-token-doc/use/config.md | 24 +- .../cn/dev33/satoken/config/SaSsoConfig.java | 8 +- .../cn/dev33/satoken/sso/SaSsoConsts.java | 65 --- .../cn/dev33/satoken/sso/SaSsoHandle.java | 72 +-- .../cn/dev33/satoken/sso/SaSsoProcessor.java | 464 ++++++++++++++++++ .../cn/dev33/satoken/sso/SaSsoTemplate.java | 98 ++-- .../java/cn/dev33/satoken/sso/SaSsoUtil.java | 47 +- .../cn/dev33/satoken/sso/name/ApiName.java | 79 +++ .../cn/dev33/satoken/sso/name/ParamName.java | 39 ++ .../reactor/spring/sso/SaSsoBeanInject.java | 2 +- .../satoken/spring/sso/SaSsoBeanInject.java | 8 +- 28 files changed, 780 insertions(+), 211 deletions(-) rename sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/{SaSsoClientApplication.java => SaSso1ClientApplication.java} (77%) rename sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/{SaSsoClientApplication.java => SaSso2ClientApplication.java} (73%) rename sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/{SaSsoClientApplication.java => SaSso3ClientApplication.java} (73%) create mode 100644 sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java create mode 100644 sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java create mode 100644 sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java diff --git a/sa-token-demo/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java b/sa-token-demo/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java index 055255b2..8328c8a2 100644 --- a/sa-token-demo/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java +++ b/sa-token-demo/sa-token-demo-sso-server/src/main/java/com/pj/sso/SsoServerController.java @@ -8,7 +8,7 @@ import org.springframework.web.servlet.ModelAndView; import com.dtflys.forest.Forest; import cn.dev33.satoken.config.SaSsoConfig; -import cn.dev33.satoken.sso.SaSsoHandle; +import cn.dev33.satoken.sso.SaSsoProcessor; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; @@ -25,11 +25,11 @@ public class SsoServerController { * http://{host}:{port}/sso/auth -- 单点登录授权地址,接受参数:redirect=授权重定向地址 * http://{host}:{port}/sso/doLogin -- 账号密码登录接口,接受参数:name、pwd * http://{host}:{port}/sso/checkTicket -- Ticket校验接口(isHttp=true时打开),接受参数:ticket=ticket码、ssoLogoutCall=单点注销回调地址 [可选] - * http://{host}:{port}/sso/logout -- 单点注销地址(isSlo=true时打开),接受参数:loginId=账号id、secretkey=接口调用秘钥 + * http://{host}:{port}/sso/signout -- 单点注销地址(isSlo=true时打开),接受参数:loginId=账号id、secretkey=接口调用秘钥 */ @RequestMapping("/sso/*") public Object ssoRequest() { - return SaSsoHandle.serverRequest(); + return SaSsoProcessor.instance.serverDister(); } // 配置SSO相关参数 diff --git a/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSsoClientApplication.java b/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSso1ClientApplication.java similarity index 77% rename from sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSsoClientApplication.java rename to sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSso1ClientApplication.java index ac60c0a1..eb4a8155 100644 --- a/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSsoClientApplication.java +++ b/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSso1ClientApplication.java @@ -9,10 +9,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * */ @SpringBootApplication -public class SaSsoClientApplication { +public class SaSso1ClientApplication { public static void main(String[] args) { - SpringApplication.run(SaSsoClientApplication.class, args); + SpringApplication.run(SaSso1ClientApplication.class, args); System.out.println("\nSa-Token SSO模式一 Client端启动成功"); } diff --git a/sa-token-demo/sa-token-demo-sso1-client/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-sso1-client/src/main/resources/application.yml index f01c205d..4c56b23a 100644 --- a/sa-token-demo/sa-token-demo-sso1-client/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-sso1-client/src/main/resources/application.yml @@ -9,7 +9,7 @@ sa-token: # SSO-Server端-单点登录授权地址 auth-url: http://sso.stp.com:9000/sso/auth # SSO-Server端-单点注销地址 - slo-url: http://sso.stp.com:9000/sso/logout + slo-url: http://sso.stp.com:9000/sso/signout # 配置 Sa-Token 单独使用的Redis连接 (此处需要和SSO-Server端连接同一个Redis) alone-redis: diff --git a/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/SaSsoClientApplication.java b/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/SaSso2ClientApplication.java similarity index 73% rename from sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/SaSsoClientApplication.java rename to sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/SaSso2ClientApplication.java index 1e33e3c4..78b1e868 100644 --- a/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/SaSsoClientApplication.java +++ b/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/SaSso2ClientApplication.java @@ -4,10 +4,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class SaSsoClientApplication { +public class SaSso2ClientApplication { public static void main(String[] args) { - SpringApplication.run(SaSsoClientApplication.class, args); + SpringApplication.run(SaSso2ClientApplication.class, args); System.out.println("\nSa-Token SSO模式二 Client端启动成功"); } diff --git a/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/h5/H5Controller.java b/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/h5/H5Controller.java index 03448242..992a7b11 100644 --- a/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/h5/H5Controller.java +++ b/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/h5/H5Controller.java @@ -4,7 +4,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import cn.dev33.satoken.sso.SaSsoHandle; +import cn.dev33.satoken.sso.SaSsoProcessor; import cn.dev33.satoken.sso.SaSsoUtil; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; @@ -34,7 +34,7 @@ public class H5Controller { // 根据ticket进行登录 @RequestMapping("/sso/doLoginByTicket") public SaResult doLoginByTicket(String ticket) { - Object loginId = SaSsoHandle.checkTicket(ticket, "/sso/doLoginByTicket"); + Object loginId = SaSsoProcessor.instance.checkTicket(ticket, "/sso/doLoginByTicket"); if(loginId != null) { StpUtil.login(loginId); return SaResult.data(StpUtil.getTokenValue()); diff --git a/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java index ecd0a19f..91746032 100644 --- a/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java +++ b/sa-token-demo/sa-token-demo-sso2-client/src/main/java/com/pj/sso/SsoClientController.java @@ -4,7 +4,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import cn.dev33.satoken.sso.SaSsoHandle; +import cn.dev33.satoken.sso.SaSsoProcessor; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; @@ -33,7 +33,7 @@ public class SsoClientController { */ @RequestMapping("/sso/*") public Object ssoRequest() { - return SaSsoHandle.clientRequest(); + return SaSsoProcessor.instance.clientDister(); } // 全局异常拦截 diff --git a/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/SaSsoClientApplication.java b/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/SaSso3ClientApplication.java similarity index 73% rename from sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/SaSsoClientApplication.java rename to sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/SaSso3ClientApplication.java index ac4dbd3b..e0e18259 100644 --- a/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/SaSsoClientApplication.java +++ b/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/SaSso3ClientApplication.java @@ -4,10 +4,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class SaSsoClientApplication { +public class SaSso3ClientApplication { public static void main(String[] args) { - SpringApplication.run(SaSsoClientApplication.class, args); + SpringApplication.run(SaSso3ClientApplication.class, args); System.out.println("\nSa-Token SSO模式三 Client端启动成功"); } diff --git a/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java index f0d66aee..111340fb 100644 --- a/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java +++ b/sa-token-demo/sa-token-demo-sso3-client/src/main/java/com/pj/sso/SsoClientController.java @@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.RestController; import com.dtflys.forest.Forest; import cn.dev33.satoken.config.SaSsoConfig; -import cn.dev33.satoken.sso.SaSsoHandle; +import cn.dev33.satoken.sso.SaSsoProcessor; import cn.dev33.satoken.sso.SaSsoUtil; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; @@ -38,7 +38,7 @@ public class SsoClientController { */ @RequestMapping("/sso/*") public Object ssoRequest() { - return SaSsoHandle.clientRequest(); + return SaSsoProcessor.instance.clientDister(); } // 配置SSO相关参数 diff --git a/sa-token-demo/sa-token-demo-sso3-client/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-sso3-client/src/main/resources/application.yml index a39d5f2e..5c2433d4 100644 --- a/sa-token-demo/sa-token-demo-sso3-client/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-sso3-client/src/main/resources/application.yml @@ -15,7 +15,7 @@ sa-token: # 打开单点注销功能 is-slo: true # 单点注销地址 - slo-url: http://sa-sso-server.com:9000/sso/logout + slo-url: http://sa-sso-server.com:9000/sso/signout # 接口调用秘钥 secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor # SSO-Server端 查询userinfo地址 diff --git a/sa-token-doc/sso/sso-apidoc.md b/sa-token-doc/sso/sso-apidoc.md index 24cc5c6c..8cb487b2 100644 --- a/sa-token-doc/sso/sso-apidoc.md +++ b/sa-token-doc/sso/sso-apidoc.md @@ -83,7 +83,7 @@ http://{host}:{port}/sso/checkTicket ### 4、单点注销接口 ``` url -http://{host}:{port}/sso/logout +http://{host}:{port}/sso/signout ``` 此接口有两种调用方式 @@ -92,7 +92,7 @@ http://{host}:{port}/sso/logout 例如: ``` url -http://{host}:{port}/sso/logout?back=xxx +http://{host}:{port}/sso/signout?back=xxx ``` 用户注销成功后将返回 back 地址 @@ -109,7 +109,7 @@ http://{host}:{port}/sso/logout?back=xxx 例如: ``` url -http://{host}:{port}/sso/logout?loginId={value}×tamp={value}&nonce={value}&sign={value} +http://{host}:{port}/sso/signout?loginId={value}×tamp={value}&nonce={value}&sign={value} ``` 将返回 json 数据结果,形如: diff --git a/sa-token-doc/sso/sso-custom-api.md b/sa-token-doc/sso/sso-custom-api.md index 0f0d3b40..ea6d933e 100644 --- a/sa-token-doc/sso/sso-custom-api.md +++ b/sa-token-doc/sso/sso-custom-api.md @@ -15,7 +15,7 @@ public class SsoServerController { // SSO-Server端:处理所有SSO相关请求 @RequestMapping("/sso/*") public Object ssoRequest() { - return SaSsoHandle.serverRequest(); + return SaSsoProcessor.instance.serverDister(); } // ... 其它代码 @@ -25,8 +25,9 @@ public class SsoServerController { 这种写法集成简单但却不够灵活。例如认证中心地址只能是:`http://{host}:{port}/sso/auth`,如果我们想要自定义其API地址,应该怎么做呢? -我们可以打开SSO模块相关源码,有关 API 的设计都定义在:[SaSsoConsts.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoConsts.java) -中,这些值从架构设计上来讲属于常量却并未使用 `final` 修饰,目的就是为了方便我们对其二次修改。 +打开SSO模块相关源码,有关 API 的设计都定义在: +[ApiName.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java) +中,我们可以对其进行二次修改。 例如,我们可以在 Main 方法启动类或者 SSO 配置方法中修改变量值: ``` java @@ -34,7 +35,7 @@ public class SsoServerController { @Autowired private void configSso(SaSsoConfig sso) { // 自定义API地址 - SaSsoConsts.Api.ssoAuth = "/sso/auth2"; + SaSsoUtil.ssoTemplate.apiName.ssoAuth = "/sso/auth2"; // ... // SSO 相关配置 @@ -60,25 +61,25 @@ public class SsoServerController { // SSO-Server:统一认证地址 @RequestMapping("/sso/auth") public Object ssoAuth() { - return SaSsoHandle.ssoAuth(); + return SaSsoProcessor.instance.ssoAuth(); } // SSO-Server:RestAPI 登录接口 @RequestMapping("/sso/doLogin") public Object ssoDoLogin() { - return SaSsoHandle.ssoDoLogin(); + return SaSsoProcessor.instance.ssoDoLogin(); } // SSO-Server:校验ticket 获取账号id @RequestMapping("/sso/checkTicket") public Object ssoCheckTicket() { - return SaSsoHandle.ssoCheckTicket(); + return SaSsoProcessor.instance.ssoCheckTicket(); } // SSO-Server:单点注销 - @RequestMapping("/sso/logout") - public Object ssoLogout() { - return SaSsoHandle.ssoServerLogout(); + @RequestMapping("/sso/signout") + public Object ssoSignout() { + return SaSsoProcessor.instance.ssoSignout(); } // ... 其它方法 diff --git a/sa-token-doc/sso/sso-h5.md b/sa-token-doc/sso/sso-h5.md index e779ab7e..0fd16c32 100644 --- a/sa-token-doc/sso/sso-h5.md +++ b/sa-token-doc/sso/sso-h5.md @@ -30,7 +30,7 @@ public class H5Controller { // 根据ticket进行登录 @RequestMapping("/sso/doLoginByTicket") public SaResult doLoginByTicket(String ticket) { - Object loginId = SaSsoHandle.checkTicket(ticket, "/sso/doLoginByTicket"); + Object loginId = SaSsoProcessor.instance.checkTicket(ticket, "/sso/doLoginByTicket"); if(loginId != null) { StpUtil.login(loginId); return SaResult.data(StpUtil.getTokenValue()); diff --git a/sa-token-doc/sso/sso-home-jump.md b/sa-token-doc/sso/sso-home-jump.md index 0db99b3f..6c9570d1 100644 --- a/sa-token-doc/sso/sso-home-jump.md +++ b/sa-token-doc/sso/sso-home-jump.md @@ -75,7 +75,7 @@ public Object ssoRequest() { if(req.isPath("/sso/auth") && req.hasParam("redirect") == false && StpUtil.isLogin()) { return SaHolder.getResponse().redirect("/home"); } - return SaSsoHandle.serverRequest(); + return SaSsoProcessor.instance.serverDister(); } ``` diff --git a/sa-token-doc/sso/sso-server.md b/sa-token-doc/sso/sso-server.md index 8b29902e..6b1288d1 100644 --- a/sa-token-doc/sso/sso-server.md +++ b/sa-token-doc/sso/sso-server.md @@ -95,7 +95,7 @@ public class SsoServerController { */ @RequestMapping("/sso/*") public Object ssoRequest() { - return SaSsoHandle.serverRequest(); + return SaSsoProcessor.instance.serverDister(); } /** diff --git a/sa-token-doc/sso/sso-type1.md b/sa-token-doc/sso/sso-type1.md index 87520f57..243df983 100644 --- a/sa-token-doc/sso/sso-type1.md +++ b/sa-token-doc/sso/sso-type1.md @@ -170,7 +170,7 @@ sa-token: # SSO-Server端-单点登录授权地址 auth-url: http://sso.stp.com:9000/sso/auth # SSO-Server端-单点注销地址 - slo-url: http://sso.stp.com:9000/sso/logout + slo-url: http://sso.stp.com:9000/sso/signout # 配置 Sa-Token 单独使用的Redis连接 (此处需要和SSO-Server端连接同一个Redis) alone-redis: @@ -195,7 +195,7 @@ server.port=9001 # SSO-Server端-单点登录授权地址 sa-token.sso.auth-url=http://sso.stp.com:9000/sso/auth # SSO-Server端-单点注销地址 -sa-token.sso.slo-url=http://sso.stp.com:9000/sso/logout +sa-token.sso.slo-url=http://sso.stp.com:9000/sso/signout # 配置 Sa-Token 单独使用的Redis连接 (此处需要和SSO-Server端连接同一个Redis) # Redis数据库索引 @@ -219,9 +219,9 @@ sa-token.alone-redis.timeout=10s * SSO模式一,Client端 Demo */ @SpringBootApplication -public class SaSsoClientApplication { +public class SaSso1ClientApplication { public static void main(String[] args) { - SpringApplication.run(SaSsoClientApplication.class, args); + SpringApplication.run(SaSso1ClientApplication.class, args); System.out.println("\nSa-Token SSO模式一 Client端启动成功"); } } diff --git a/sa-token-doc/sso/sso-type2.md b/sa-token-doc/sso/sso-type2.md index 9cbfe3be..0499d3fb 100644 --- a/sa-token-doc/sso/sso-type2.md +++ b/sa-token-doc/sso/sso-type2.md @@ -151,7 +151,7 @@ public class SsoClientController { */ @RequestMapping("/sso/*") public Object ssoRequest() { - return SaSsoHandle.clientRequest(); + return SaSsoProcessor.instance.clientDister(); } } @@ -220,9 +220,9 @@ sa-token.alone-redis.timeout=10s #### 3.5、写启动类 ``` java @SpringBootApplication -public class SaSsoClientApplication { +public class SaSso2ClientApplication { public static void main(String[] args) { - SpringApplication.run(SaSsoClientApplication.class, args); + SpringApplication.run(SaSso2ClientApplication.class, args); System.out.println("\nSa-Token-SSO Client端启动成功"); } } diff --git a/sa-token-doc/sso/sso-type3.md b/sa-token-doc/sso/sso-type3.md index 1ee82d46..336f7265 100644 --- a/sa-token-doc/sso/sso-type3.md +++ b/sa-token-doc/sso/sso-type3.md @@ -236,7 +236,7 @@ sa-token: # 打开单点注销功能 is-slo: true # 单点注销地址 - slo-url: http://sa-sso-server.com:9000/sso/logout + slo-url: http://sa-sso-server.com:9000/sso/signout # 接口调用秘钥 secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor ``` @@ -245,7 +245,7 @@ sa-token: # 打开单点注销功能 sa-token.sso.is-slo=true # 单点注销地址 -sa-token.sso.slo-url=http://sa-sso-server.com:9000/sso/logout +sa-token.sso.slo-url=http://sa-sso-server.com:9000/sso/signout # 接口调用秘钥 sa-token.sso.secretkey=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor ``` diff --git a/sa-token-doc/use/config.md b/sa-token-doc/use/config.md index f5fbc7be..556e3e98 100644 --- a/sa-token-doc/use/config.md +++ b/sa-token-doc/use/config.md @@ -154,7 +154,7 @@ Cookie相关配置: ### 单点登录相关配置 -Server 端: +Server 端配置: | 参数名称 | 类型 | 默认值 | 说明 | | :-------- | :-------- | :-------- | :-------- | @@ -165,19 +165,19 @@ Server 端: | secretkey | String | null | 调用秘钥 (用于SSO模式三单点注销的接口通信身份校验) | -Client 端: +Client 端配置: | 参数名称 | 类型 | 默认值 | 说明 | | :-------- | :-------- | :-------- | :-------- | -| authUrl | String | null | 配置 Server 端单点登录授权地址 | -| isSlo | Boolean | false | 是否打开单点注销功能 | -| isHttp | Boolean | false | 是否打开模式三(此值为 true 时将使用 http 请求:校验 ticket 值、单点注销、获取 userinfo),参考:[详解](/use/config?id=配置项详解:isHttp) | -| checkTicketUrl| String | null | 配置 Server 端的 `ticket` 校验地址 | -| userinfoUrl | String | null | 配置 Server 端查询 `userinfo` 地址 | -| sloUrl | String | null | 配置 Server 端单点注销地址 | -| ssoLogoutCall | String | null | 配置当前 Client 端的单点注销回调URL (为空时自动获取) | -| secretkey | String | null | 接口调用秘钥 (用于SSO模式三单点注销的接口通信身份校验) | -| serverUrl | String | null | 配置 Server 端主机总地址,拼接在 `authUrl`、`checkTicketUrl`、`userinfoUrl`、`sloUrl` 属性前面,用以简化各种 url 配置,[详解](/use/config?id=配置项详解:serverUrl) | +| authUrl | String | /sso/auth | 配置 Server 端单点登录授权地址 | +| isSlo | Boolean | false | 是否打开单点注销功能 | +| isHttp | Boolean | false | 是否打开模式三(此值为 true 时将使用 http 请求:校验 ticket 值、单点注销、获取 userinfo),参考:[详解](/use/config?id=配置项详解:isHttp) | +| checkTicketUrl| String | /sso/checkTicket | 配置 Server 端的 `ticket` 校验地址 | +| userinfoUrl | String | /sso/userinfo | 配置 Server 端查询 `userinfo` 地址 | +| sloUrl | String | /sso/signout | 配置 Server 端单点注销地址 | +| ssoLogoutCall | String | null | 配置当前 Client 端的单点注销回调URL (为空时自动获取) | +| secretkey | String | null | 接口调用秘钥 (用于SSO模式三单点注销的接口通信身份校验) | +| serverUrl | String | null | 配置 Server 端主机总地址,拼接在 `authUrl`、`checkTicketUrl`、`userinfoUrl`、`sloUrl` 属性前面,用以简化各种 url 配置,[详解](/use/config?id=配置项详解:serverUrl) | 配置示例: @@ -332,7 +332,7 @@ sa-token: # SSO-Server端 ticket校验地址 check-ticket-url: http://sa-sso-server.com:9000/sso/checkTicket # 单点注销地址 - slo-url: http://sa-sso-server.com:9000/sso/logout + slo-url: http://sa-sso-server.com:9000/sso/signout # SSO-Server端 查询userinfo地址 userinfo-url: http://sa-sso-server.com:9000/sso/userinfo ``` diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/config/SaSsoConfig.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/config/SaSsoConfig.java index 5ec0a52d..3c3d0284 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/config/SaSsoConfig.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/config/SaSsoConfig.java @@ -58,17 +58,17 @@ public class SaSsoConfig implements Serializable { /** * 是否打开单点注销功能 */ - // public Boolean isSlo = true; // 同上 + // public Boolean isSlo = true; // 同Server端 /** * 是否打开模式三(此值为 true 时将使用 http 请求:校验ticket值、单点注销、获取userinfo) */ - // public Boolean isHttp = false; // 同上 + // public Boolean isHttp = false; // 同Server端 /** * 接口调用秘钥 (用于SSO模式三单点注销的接口通信身份校验) */ - // public String secretkey; // 同上 + // public String secretkey; // 同Server端 /** * 配置 Server 端的 ticket 校验地址 @@ -83,7 +83,7 @@ public class SaSsoConfig implements Serializable { /** * 配置 Server 端单点注销地址 */ - public String sloUrl = "/sso/logout"; + public String sloUrl = "/sso/signout"; /** * 配置当前 Client 端的单点注销回调URL (为空时自动获取) diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoConsts.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoConsts.java index 307649f2..564caadd 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoConsts.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoConsts.java @@ -7,71 +7,6 @@ package cn.dev33.satoken.sso; */ public class SaSsoConsts { - /** - * 所有API接口 - * @author kong - */ - public static final class Api { - - /** SSO-Server端:授权地址 */ - public static String ssoAuth = "/sso/auth"; - - /** SSO-Server端:RestAPI 登录接口 */ - public static String ssoDoLogin = "/sso/doLogin"; - - /** SSO-Server端:校验ticket 获取账号id */ - public static String ssoCheckTicket = "/sso/checkTicket"; - - /** SSO-Server端:获取userinfo */ - public static String ssoUserinfo = "/sso/userinfo"; - - /** SSO-Server端 (and Client端):单点注销地址 */ - public static String ssoLogout = "/sso/logout"; - - /** SSO-Client端:登录地址 */ - public static String ssoLogin = "/sso/login"; - - /** SSO-Client端:单点注销的回调 */ - public static String ssoLogoutCall = "/sso/logoutCall"; - - } - - /** - * 所有参数名称 - * @author kong - */ - public static final class ParamName { - - /** redirect参数名称 */ - public static String redirect = "redirect"; - - /** ticket参数名称 */ - public static String ticket = "ticket"; - - /** back参数名称 */ - public static String back = "back"; - - /** mode参数名称 */ - public static String mode = "mode"; - - /** loginId参数名称 */ - public static String loginId = "loginId"; - - /** secretkey参数名称 */ - public static String secretkey = "secretkey"; - - /** Client端单点注销时-回调URL 参数名称 */ - public static String ssoLogoutCall = "ssoLogoutCall"; - - public static String name = "name"; - public static String pwd = "pwd"; - - public static String timestamp = "timestamp"; - public static String nonce = "nonce"; - public static String sign = "sign"; - - } - /** Client端单点注销回调URL的Set集合,存储在Session中使用的key */ public static final String SLO_CALLBACK_SET_KEY = "SLO_CALLBACK_SET_KEY_"; diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoHandle.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoHandle.java index e59e2e08..2fa39884 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoHandle.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoHandle.java @@ -4,10 +4,10 @@ import cn.dev33.satoken.config.SaSsoConfig; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.context.model.SaResponse; -import cn.dev33.satoken.sso.SaSsoConsts.Api; -import cn.dev33.satoken.sso.SaSsoConsts.ParamName; import cn.dev33.satoken.sso.exception.SaSsoException; import cn.dev33.satoken.sso.exception.SaSsoExceptionCode; +import cn.dev33.satoken.sso.name.ApiName; +import cn.dev33.satoken.sso.name.ParamName; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaResult; @@ -17,8 +17,20 @@ import cn.dev33.satoken.util.SaResult; * @author kong * */ +@Deprecated public class SaSsoHandle { + /** + * 所有 API 名称 + */ + public static ApiName apiName = new ApiName(); + + /** + * 所有参数名称 + */ + public static ParamName paramName = new ParamName(); + + // ----------- SSO-Server 端路由分发 /** @@ -34,27 +46,27 @@ public class SaSsoHandle { // ------------------ 路由分发 ------------------ // SSO-Server端:授权地址 - if(req.isPath(Api.ssoAuth)) { + if(req.isPath(apiName.ssoAuth)) { return ssoAuth(); } // SSO-Server端:RestAPI 登录接口 - if(req.isPath(Api.ssoDoLogin)) { + if(req.isPath(apiName.ssoDoLogin)) { return ssoDoLogin(); } // SSO-Server端:校验ticket 获取账号id - if(req.isPath(Api.ssoCheckTicket) && cfg.getIsHttp()) { + if(req.isPath(apiName.ssoCheckTicket) && cfg.getIsHttp()) { return ssoCheckTicket(); } // SSO-Server端:单点注销 [用户访问式] (不带loginId参数) - if(req.isPath(Api.ssoLogout) && cfg.getIsSlo() && req.hasParam(ParamName.loginId) == false) { + if(req.isPath(apiName.ssoSignout) && cfg.getIsSlo() && req.hasParam(paramName.loginId) == false) { return ssoLogoutByUserVisit(); } // SSO-Server端:单点注销 [Client调用式] (带loginId参数 & isHttp=true) - if(req.isPath(Api.ssoLogout) && cfg.getIsHttp() && cfg.getIsSlo() && req.hasParam(ParamName.loginId)) { + if(req.isPath(apiName.ssoSignout) && cfg.getIsHttp() && cfg.getIsSlo() && req.hasParam(paramName.loginId)) { return ssoLogoutByClientHttp(); } @@ -71,7 +83,7 @@ public class SaSsoHandle { SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); SaSsoConfig cfg = SaSsoManager.getConfig(); - StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic; + StpLogic stpLogic = SaSsoUtil.ssoTemplate.getStpLogic(); // ---------- 此处有两种情况分开处理: // ---- 情况1:在SSO认证中心尚未登录,需要先去登录 @@ -79,16 +91,16 @@ public class SaSsoHandle { return cfg.getNotLoginView().get(); } // ---- 情况2:在SSO认证中心已经登录,需要重定向回 Client 端,而这又分为两种方式: - String mode = req.getParam(ParamName.mode, ""); + String mode = req.getParam(paramName.mode, ""); // 方式1:直接重定向回Client端 (mode=simple) if(mode.equals(SaSsoConsts.MODE_SIMPLE)) { - String redirect = req.getParam(ParamName.redirect); + String redirect = req.getParam(paramName.redirect); SaSsoUtil.checkRedirectUrl(redirect); return res.redirect(redirect); } else { // 方式2:带着ticket参数重定向回Client端 (mode=ticket) - String redirectUrl = SaSsoUtil.buildRedirectUrl(stpLogic.getLoginId(), req.getParam(ParamName.redirect)); + String redirectUrl = SaSsoUtil.buildRedirectUrl(stpLogic.getLoginId(), req.getParam(paramName.redirect)); return res.redirect(redirectUrl); } } @@ -103,7 +115,7 @@ public class SaSsoHandle { SaSsoConfig cfg = SaSsoManager.getConfig(); // 处理 - return cfg.getDoLoginHandle().apply(req.getParam(ParamName.name), req.getParam(ParamName.pwd)); + return cfg.getDoLoginHandle().apply(req.getParam(paramName.name), req.getParam(paramName.pwd)); } /** @@ -113,8 +125,8 @@ public class SaSsoHandle { public static Object ssoCheckTicket() { // 获取参数 SaRequest req = SaHolder.getRequest(); - String ticket = req.getParamNotNull(ParamName.ticket); - String sloCallback = req.getParam(ParamName.ssoLogoutCall); + String ticket = req.getParamNotNull(paramName.ticket); + String sloCallback = req.getParam(paramName.ssoLogoutCall); // 校验ticket,获取 loginId Object loginId = SaSsoUtil.checkTicket(ticket); @@ -138,7 +150,7 @@ public class SaSsoHandle { // 获取对象 SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); - Object loginId = SaSsoUtil.saSsoTemplate.stpLogic.getLoginIdDefaultNull(); + Object loginId = SaSsoUtil.ssoTemplate.getStpLogic().getLoginIdDefaultNull(); // 单点注销 if(SaFoxUtil.isNotEmpty(loginId)) { @@ -156,7 +168,7 @@ public class SaSsoHandle { public static Object ssoLogoutByClientHttp() { // 获取参数 SaRequest req = SaHolder.getRequest(); - String loginId = req.getParam(ParamName.loginId); + String loginId = req.getParam(paramName.loginId); // step.1 校验签名 SaSsoUtil.checkSign(req); @@ -184,22 +196,22 @@ public class SaSsoHandle { // ------------------ 路由分发 ------------------ // ---------- SSO-Client端:登录地址 - if(req.isPath(Api.ssoLogin)) { + if(req.isPath(apiName.ssoLogin)) { return ssoLogin(); } // ---------- SSO-Client端:单点注销 [模式二] - if(req.isPath(Api.ssoLogout) && cfg.getIsSlo() && cfg.getIsHttp() == false) { + if(req.isPath(apiName.ssoLogout) && cfg.getIsSlo() && cfg.getIsHttp() == false) { return ssoLogoutType2(); } // ---------- SSO-Client端:单点注销 [模式三] - if(req.isPath(Api.ssoLogout) && cfg.getIsSlo() && cfg.getIsHttp()) { + if(req.isPath(apiName.ssoLogout) && cfg.getIsSlo() && cfg.getIsHttp()) { return ssoLogoutType3(); } // ---------- SSO-Client端:单点注销的回调 [模式三] - if(req.isPath(Api.ssoLogoutCall) && cfg.getIsSlo() && cfg.getIsHttp()) { + if(req.isPath(apiName.ssoLogoutCall) && cfg.getIsSlo() && cfg.getIsHttp()) { return ssoLogoutCall(); } @@ -216,11 +228,11 @@ public class SaSsoHandle { SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); SaSsoConfig cfg = SaSsoManager.getConfig(); - StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic; + StpLogic stpLogic = SaSsoUtil.ssoTemplate.getStpLogic(); // 获取参数 - String back = req.getParam(ParamName.back, "/"); - String ticket = req.getParam(ParamName.ticket); + String back = req.getParam(paramName.back, "/"); + String ticket = req.getParam(paramName.ticket); // 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回 if(stpLogic.isLogin()) { @@ -236,7 +248,7 @@ public class SaSsoHandle { return res.redirect(serverAuthUrl); } else { // ------- 1、校验ticket,获取 loginId - Object loginId = checkTicket(ticket, Api.ssoLogin); + Object loginId = checkTicket(ticket, apiName.ssoLogin); // Be: 如果开发者自定义了处理逻辑 if(cfg.getTicketResultHandle() != null) { @@ -262,7 +274,7 @@ public class SaSsoHandle { // 获取对象 SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); - StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic; + StpLogic stpLogic = SaSsoUtil.ssoTemplate.getStpLogic(); // 开始处理 stpLogic.logout(); @@ -279,7 +291,7 @@ public class SaSsoHandle { // 获取对象 SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); - StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic; + StpLogic stpLogic = SaSsoUtil.ssoTemplate.getStpLogic(); // 如果未登录,则无需注销 if(stpLogic.isLogin() == false) { @@ -310,10 +322,10 @@ public class SaSsoHandle { public static Object ssoLogoutCall() { // 获取对象 SaRequest req = SaHolder.getRequest(); - StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic; + StpLogic stpLogic = SaSsoUtil.ssoTemplate.getStpLogic(); // 获取参数 - String loginId = req.getParamNotNull(ParamName.loginId); + String loginId = req.getParamNotNull(paramName.loginId); // 注销当前应用端会话 SaSsoUtil.checkSign(req); @@ -339,7 +351,7 @@ public class SaSsoHandle { * 2. 有back参数,值为url -> 跳转到此url地址 * 3. 无back参数 -> 返回json数据 */ - String back = req.getParam(ParamName.back); + String back = req.getParam(paramName.back); if(SaFoxUtil.isNotEmpty(back)) { if(back.equals(SaSsoConsts.SELF)) { return ""; @@ -372,7 +384,7 @@ public class SaSsoHandle { } // 如果提供了当前 uri,则根据此值来计算: else if(SaFoxUtil.isNotEmpty(currUri)) { - ssoLogoutCall = SaHolder.getRequest().getUrl().replace(currUri, Api.ssoLogoutCall); + ssoLogoutCall = SaHolder.getRequest().getUrl().replace(currUri, apiName.ssoLogoutCall); } // 否则视为不注册单点注销回调地址 else { diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java new file mode 100644 index 00000000..8bda2550 --- /dev/null +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java @@ -0,0 +1,464 @@ +package cn.dev33.satoken.sso; + +import cn.dev33.satoken.config.SaSsoConfig; +import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.sso.exception.SaSsoException; +import cn.dev33.satoken.sso.exception.SaSsoExceptionCode; +import cn.dev33.satoken.sso.name.ApiName; +import cn.dev33.satoken.sso.name.ParamName; +import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.util.SaFoxUtil; +import cn.dev33.satoken.util.SaResult; + +/** + * SSO 请求处理器 + * + * @author kong + * @since 2022-10-25 + */ +public class SaSsoProcessor { + + /** + * 底层 SaSsoTemplate 对象 + */ + public SaSsoTemplate ssoTemplate = SaSsoUtil.ssoTemplate; + + // ----------- SSO-Server 端路由分发 ----------- + + /** + * 分发 Server 端所有请求 + * @return 处理结果 + */ + public Object serverDister() { + + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaSsoConfig cfg = SaSsoManager.getConfig(); + ApiName apiName = ssoTemplate.apiName; + + // ------------------ 路由分发 ------------------ + + // ---------- SSO-Server端:授权地址 + if(req.isPath(apiName.ssoAuth)) { + return ssoAuth(); + } + + // ---------- SSO-Server端:RestAPI 登录接口 + if(req.isPath(apiName.ssoDoLogin)) { + return ssoDoLogin(); + } + + // ---------- SSO-Server端:校验ticket 获取账号id + if(req.isPath(apiName.ssoCheckTicket) && cfg.getIsHttp()) { + return ssoCheckTicket(); + } + + // ---------- SSO-Server端:单点注销 + if(req.isPath(apiName.ssoSignout)) { + return ssoSignout(); + } + + // 默认返回 + return SaSsoConsts.NOT_HANDLE; + } + + /** + * SSO-Server端:授权地址 + * @return 处理结果 + */ + public Object ssoAuth() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaResponse res = SaHolder.getResponse(); + SaSsoConfig cfg = SaSsoManager.getConfig(); + StpLogic stpLogic = ssoTemplate.getStpLogic(); + ParamName paramName = ssoTemplate.paramName; + + // ---------- 此处有两种情况分开处理: + // ---- 情况1:在SSO认证中心尚未登录,需要先去登录 + if(stpLogic.isLogin() == false) { + return cfg.getNotLoginView().get(); + } + // ---- 情况2:在SSO认证中心已经登录,需要重定向回 Client 端,而这又分为两种方式: + String mode = req.getParam(paramName.mode, ""); + + // 方式1:直接重定向回Client端 (mode=simple) + if(mode.equals(SaSsoConsts.MODE_SIMPLE)) { + String redirect = req.getParam(paramName.redirect); + ssoTemplate.checkRedirectUrl(redirect); + return res.redirect(redirect); + } else { + // 方式2:带着ticket参数重定向回Client端 (mode=ticket) + String redirectUrl = ssoTemplate.buildRedirectUrl(stpLogic.getLoginId(), req.getParam(paramName.redirect)); + return res.redirect(redirectUrl); + } + } + + /** + * SSO-Server端:RestAPI 登录接口 + * @return 处理结果 + */ + public Object ssoDoLogin() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaSsoConfig cfg = SaSsoManager.getConfig(); + ParamName paramName = ssoTemplate.paramName; + + // 处理 + return cfg.getDoLoginHandle().apply(req.getParam(paramName.name), req.getParam(paramName.pwd)); + } + + /** + * SSO-Server端:校验ticket 获取账号id [模式三] + * @return 处理结果 + */ + public Object ssoCheckTicket() { + ParamName paramName = ssoTemplate.paramName; + + // 获取参数 + SaRequest req = SaHolder.getRequest(); + String ticket = req.getParamNotNull(paramName.ticket); + String sloCallback = req.getParam(paramName.ssoLogoutCall); + + // 校验ticket,获取 loginId + Object loginId = ssoTemplate.checkTicket(ticket); + + // 注册此客户端的单点注销回调URL + ssoTemplate.registerSloCallbackUrl(loginId, sloCallback); + + // 给 client 端响应结果 + if(SaFoxUtil.isEmpty(loginId)) { + return SaResult.error("无效ticket:" + ticket); + } else { + return SaResult.data(loginId); + } + } + + /** + * SSO-Server端:单点注销 + * @return 处理结果 + */ + public Object ssoSignout() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaSsoConfig cfg = SaSsoManager.getConfig(); + ParamName paramName = ssoTemplate.paramName; + + // SSO-Server端:单点注销 [用户访问式] (不带loginId参数) + if(cfg.getIsSlo() && req.hasParam(paramName.loginId) == false) { + return ssoSignoutByUserVisit(); + } + + // SSO-Server端:单点注销 [Client调用式] (带loginId参数 & isHttp=true) + if(cfg.getIsHttp() && cfg.getIsSlo() && req.hasParam(paramName.loginId)) { + return ssoSignoutByClientHttp(); + } + + // 默认返回 + return SaSsoConsts.NOT_HANDLE; + } + + /** + * SSO-Server端:单点注销 [用户访问式] + * @return 处理结果 + */ + public Object ssoSignoutByUserVisit() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaResponse res = SaHolder.getResponse(); + Object loginId = ssoTemplate.getStpLogic().getLoginIdDefaultNull(); + + // 单点注销 + if(SaFoxUtil.isNotEmpty(loginId)) { + ssoTemplate.ssoLogout(loginId); + } + + // 完成 + return ssoLogoutBack(req, res); + } + + /** + * SSO-Server端:单点注销 [Client调用式] + * @return 处理结果 + */ + public Object ssoSignoutByClientHttp() { + ParamName paramName = ssoTemplate.paramName; + + // 获取参数 + SaRequest req = SaHolder.getRequest(); + String loginId = req.getParam(paramName.loginId); + + // step.1 校验签名 + ssoTemplate.checkSign(req); + + // step.2 单点注销 + ssoTemplate.ssoLogout(loginId); + + // 响应 + return SaResult.ok(); + } + + + // ----------- SSO-Client 端路由分发 ----------- + + /** + * 分发 Client 端所有请求 + * @return 处理结果 + */ + public Object clientDister() { + ApiName apiName = ssoTemplate.apiName; + + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaSsoConfig cfg = SaSsoManager.getConfig(); + + // ------------------ 路由分发 ------------------ + + // ---------- SSO-Client端:登录地址 + if(req.isPath(apiName.ssoLogin)) { + return ssoLogin(); + } + + // ---------- SSO-Client端:单点注销 + if(req.isPath(apiName.ssoLogout)) { + return ssoLogout(); + } + + // ---------- SSO-Client端:单点注销的回调 [模式三] + if(req.isPath(apiName.ssoLogoutCall) && cfg.getIsSlo() && cfg.getIsHttp()) { + return ssoLogoutCall(); + } + + // 默认返回 + return SaSsoConsts.NOT_HANDLE; + } + + /** + * SSO-Client端:登录地址 + * @return 处理结果 + */ + public Object ssoLogin() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaResponse res = SaHolder.getResponse(); + SaSsoConfig cfg = SaSsoManager.getConfig(); + StpLogic stpLogic = ssoTemplate.getStpLogic(); + ApiName apiName = ssoTemplate.apiName; + ParamName paramName = ssoTemplate.paramName; + + // 获取参数 + String back = req.getParam(paramName.back, "/"); + String ticket = req.getParam(paramName.ticket); + + // 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回 + if(stpLogic.isLogin()) { + return res.redirect(back); + } + /* + * 此时有两种情况: + * 情况1:ticket无值,说明此请求是Client端访问,需要重定向至SSO认证中心 + * 情况2:ticket有值,说明此请求从SSO认证中心重定向而来,需要根据ticket进行登录 + */ + if(ticket == null) { + String serverAuthUrl = ssoTemplate.buildServerAuthUrl(SaHolder.getRequest().getUrl(), back); + return res.redirect(serverAuthUrl); + } else { + // ------- 1、校验ticket,获取 loginId + Object loginId = checkTicket(ticket, apiName.ssoLogin); + + // Be: 如果开发者自定义了处理逻辑 + if(cfg.getTicketResultHandle() != null) { + return cfg.getTicketResultHandle().apply(loginId, back); + } + + // ------- 2、如果 loginId 无值,说明 ticket 无效 + if(SaFoxUtil.isEmpty(loginId)) { + throw new SaSsoException("无效ticket:" + ticket).setCode(SaSsoExceptionCode.CODE_20004); + } else { + // 3、如果 loginId 有值,说明 ticket 有效,此时进行登录并重定向至back地址 + stpLogic.login(loginId); + return res.redirect(back); + } + } + } + + /** + * SSO-Client端:单点注销 + * @return 处理结果 + */ + public Object ssoLogout() { + // 获取对象 + SaSsoConfig cfg = SaSsoManager.getConfig(); + + // ---------- SSO-Client端:单点注销 [模式二] + if(cfg.getIsSlo() && cfg.getIsHttp() == false) { + return ssoLogoutType2(); + } + + // ---------- SSO-Client端:单点注销 [模式三] + if(cfg.getIsSlo() && cfg.getIsHttp()) { + return ssoLogoutType3(); + } + + // 默认返回 + return SaSsoConsts.NOT_HANDLE; + } + + /** + * SSO-Client端:单点注销 [模式二] + * @return 处理结果 + */ + public Object ssoLogoutType2() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaResponse res = SaHolder.getResponse(); + StpLogic stpLogic = ssoTemplate.getStpLogic(); + + // 开始处理 + stpLogic.logout(); + + // 返回 + return ssoLogoutBack(req, res); + } + + /** + * SSO-Client端:单点注销 [模式三] + * @return 处理结果 + */ + public Object ssoLogoutType3() { + // 获取对象 + SaRequest req = SaHolder.getRequest(); + SaResponse res = SaHolder.getResponse(); + StpLogic stpLogic = ssoTemplate.getStpLogic(); + + // 如果未登录,则无需注销 + if(stpLogic.isLogin() == false) { + return SaResult.ok(); + } + + // 调用 sso-server 认证中心单点注销API + String url = ssoTemplate.buildSloUrl(stpLogic.getLoginId()); + SaResult result = ssoTemplate.request(url); + + // 校验响应状态码 + if(result.getCode() == SaResult.CODE_SUCCESS) { + // 极端场景下,sso-server 中心的单点注销可能并不会通知到此 client 端,所以这里需要再补一刀 + if(stpLogic.isLogin()) { + stpLogic.logout(); + } + return ssoLogoutBack(req, res); + } else { + // 将 sso-server 回应的消息作为异常抛出 + throw new SaSsoException(result.getMsg()).setCode(SaSsoExceptionCode.CODE_20006); + } + } + + /** + * SSO-Client端:单点注销的回调 [模式三] + * @return 处理结果 + */ + public Object ssoLogoutCall() { + ParamName paramName = ssoTemplate.paramName; + + // 获取对象 + SaRequest req = SaHolder.getRequest(); + StpLogic stpLogic = ssoTemplate.getStpLogic(); + + // 获取参数 + String loginId = req.getParamNotNull(paramName.loginId); + + // 注销当前应用端会话 + ssoTemplate.checkSign(req); + stpLogic.logout(loginId); + + // 响应 + return SaResult.ok("单点注销回调成功"); + } + + + // ----------- 工具方法 + + /** + * 封装:单点注销成功后返回结果 + * @param req SaRequest对象 + * @param res SaResponse对象 + * @return 返回结果 + */ + public Object ssoLogoutBack(SaRequest req, SaResponse res) { + ParamName paramName = ssoTemplate.paramName; + + /* + * 三种情况: + * 1. 有back参数,值为SELF -> 回退一级并刷新 + * 2. 有back参数,值为url -> 跳转到此url地址 + * 3. 无back参数 -> 返回json数据 + */ + String back = req.getParam(paramName.back); + if(SaFoxUtil.isNotEmpty(back)) { + if(back.equals(SaSsoConsts.SELF)) { + return ""; + } + return res.redirect(back); + } else { + return SaResult.ok("单点注销成功"); + } + } + + /** + * 封装:校验ticket,取出loginId + * @param ticket ticket码 + * @param currUri 当前路由的uri,用于计算单点注销回调地址 + * @return loginId + */ + public Object checkTicket(String ticket, String currUri) { + SaSsoConfig cfg = SaSsoManager.getConfig(); + ApiName apiName = ssoTemplate.apiName; + + // --------- 两种模式 + if(cfg.getIsHttp()) { + // q1、使用模式三:使用 http 请求从认证中心校验ticket + + // 计算当前 sso-client 的单点注销回调地址 + String ssoLogoutCall = null; + if(cfg.getIsSlo()) { + // 如果配置了回调地址,就使用配置的值: + if(SaFoxUtil.isNotEmpty(cfg.getSsoLogoutCall())) { + ssoLogoutCall = cfg.getSsoLogoutCall(); + } + // 如果提供了当前 uri,则根据此值来计算: + else if(SaFoxUtil.isNotEmpty(currUri)) { + ssoLogoutCall = SaHolder.getRequest().getUrl().replace(currUri, apiName.ssoLogoutCall); + } + // 否则视为不注册单点注销回调地址 + else { + } + } + + // 发起请求 + String checkUrl = ssoTemplate.buildCheckTicketUrl(ticket, ssoLogoutCall); + SaResult result = ssoTemplate.request(checkUrl); + + // 校验 + if(result.getCode() == SaResult.CODE_SUCCESS) { + return result.getData(); + } else { + // 将 sso-server 回应的消息作为异常抛出 + throw new SaSsoException(result.getMsg()).setCode(SaSsoExceptionCode.CODE_20005); + } + } else { + // q2、使用模式二:直连Redis校验ticket + return ssoTemplate.checkTicket(ticket); + } + } + + + // ----------- 全局默认实例 ----------- + + /** + * 全局默认实例 + */ + public static SaSsoProcessor instance = new SaSsoProcessor(); + +} diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java index eaa229fa..38f05c19 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java @@ -11,9 +11,10 @@ import cn.dev33.satoken.SaManager; import cn.dev33.satoken.config.SaSsoConfig; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.session.SaSession; -import cn.dev33.satoken.sso.SaSsoConsts.ParamName; import cn.dev33.satoken.sso.exception.SaSsoException; import cn.dev33.satoken.sso.exception.SaSsoExceptionCode; +import cn.dev33.satoken.sso.name.ApiName; +import cn.dev33.satoken.sso.name.ParamName; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.strategy.SaStrategy; @@ -26,17 +27,54 @@ import cn.dev33.satoken.util.SaResult; * */ public class SaSsoTemplate { + + // ---------------------- 全局配置 ---------------------- + + /** + * 所有 API 名称 + */ + public ApiName apiName = new ApiName(); + + + /** + * 所有参数名称 + */ + public ParamName paramName = new ParamName(); + + /** + * @param paramName 替换 paramName 对象 + * @return 对象自身 + */ + public SaSsoTemplate setParamName(ParamName paramName) { + this.paramName = paramName; + return this; + } /** - * 单点登录模块使用的 StpLogic 对象 + * @param apiName 替换 apiName 对象 + * @return 对象自身 */ - public StpLogic stpLogic; - public SaSsoTemplate(StpLogic stpLogic) { - this.stpLogic = stpLogic; + public SaSsoTemplate setApiName(ApiName apiName) { + this.apiName = apiName; + return this; } - public SaSsoTemplate() { - this.stpLogic = StpUtil.stpLogic; + + /** + * 获取底层使用的会话对象 + * @return / + */ + public StpLogic getStpLogic() { + return StpUtil.stpLogic; } + + /** + * 获取底层使用的配置对象 + * @return / + */ + public SaSsoConfig getSsoConfig() { + return SaSsoManager.getConfig(); + } + // ---------------------- Ticket 操作 ---------------------- @@ -205,7 +243,7 @@ public class SaSsoTemplate { if(SaFoxUtil.isEmpty(loginId) || SaFoxUtil.isEmpty(sloCallbackUrl)) { return; } - SaSession session = stpLogic.getSessionByLoginId(loginId); + SaSession session = getStpLogic().getSessionByLoginId(loginId); Set urlSet = session.get(SaSsoConsts.SLO_CALLBACK_SET_KEY, ()-> new HashSet()); urlSet.add(sloCallbackUrl); session.set(SaSsoConsts.SLO_CALLBACK_SET_KEY, urlSet); @@ -218,7 +256,7 @@ public class SaSsoTemplate { public void ssoLogout(Object loginId) { // 如果这个账号尚未登录,则无操作 - SaSession session = stpLogic.getSessionByLoginId(loginId, false); + SaSession session = getStpLogic().getSessionByLoginId(loginId, false); if(session == null) { return; } @@ -232,7 +270,7 @@ public class SaSsoTemplate { } // step.2 Server端注销 - stpLogic.logout(loginId); + getStpLogic().logout(loginId); } /** @@ -269,10 +307,10 @@ public class SaSsoTemplate { * 部分 Servlet 版本 request.getRequestURL() 返回的 url 带有 query 参数,形如:http://domain.com?id=1, * 如果不加判断会造成最终生成的 serverAuthUrl 带有双 back 参数 ,这个 if 判断正是为了解决此问题 */ - if(clientLoginUrl.indexOf(ParamName.back + "=" + back) == -1) { - clientLoginUrl = SaFoxUtil.joinParam(clientLoginUrl, ParamName.back, back); + if(clientLoginUrl.indexOf(paramName.back + "=" + back) == -1) { + clientLoginUrl = SaFoxUtil.joinParam(clientLoginUrl, paramName.back, back); } - String serverAuthUrl = SaFoxUtil.joinParam(serverUrl, ParamName.redirect, clientLoginUrl); + String serverAuthUrl = SaFoxUtil.joinParam(serverUrl, paramName.redirect, clientLoginUrl); // 返回 return serverAuthUrl; @@ -296,7 +334,7 @@ public class SaSsoTemplate { String ticket = createTicket(loginId); // 构建 授权重定向地址 (Server端 根据此地址向 Client端 下放Ticket) - return SaFoxUtil.joinParam(encodeBackParam(redirect), ParamName.ticket, ticket); + return SaFoxUtil.joinParam(encodeBackParam(redirect), paramName.ticket, ticket); } /** @@ -307,16 +345,16 @@ public class SaSsoTemplate { public String encodeBackParam(String url) { // 获取back参数所在位置 - int index = url.indexOf("?" + ParamName.back + "="); + int index = url.indexOf("?" + paramName.back + "="); if(index == -1) { - index = url.indexOf("&" + ParamName.back + "="); + index = url.indexOf("&" + paramName.back + "="); if(index == -1) { return url; } } // 开始编码 - int length = ParamName.back.length() + 2; + int length = paramName.back.length() + 2; String back = url.substring(index + length); back = SaFoxUtil.encodeUrl(back); @@ -347,11 +385,11 @@ public class SaSsoTemplate { String url = SaSsoManager.getConfig().splicingCheckTicketUrl(); // 拼接ticket参数 - url = SaFoxUtil.joinParam(url, ParamName.ticket, ticket); + url = SaFoxUtil.joinParam(url, paramName.ticket, ticket); // 拼接单点注销时的回调URL if(ssoLogoutCallUrl != null) { - url = SaFoxUtil.joinParam(url, ParamName.ssoLogoutCall, ssoLogoutCallUrl); + url = SaFoxUtil.joinParam(url, paramName.ssoLogoutCall, ssoLogoutCallUrl); } // 返回 @@ -437,9 +475,9 @@ public class SaSsoTemplate { */ public String getSign(Object loginId, String timestamp, String nonce, String secretkey) { Map map = new TreeMap<>(); - map.put(ParamName.loginId, loginId); - map.put(ParamName.timestamp, timestamp); - map.put(ParamName.nonce, nonce); + map.put(paramName.loginId, loginId); + map.put(paramName.timestamp, timestamp); + map.put(paramName.nonce, nonce); return SaManager.getSaSignTemplate().createSign(map, secretkey); } @@ -457,10 +495,10 @@ public class SaSsoTemplate { String sign = getSign(loginId, timestamp, nonce, getSecretkey()); // 追加到url - url = SaFoxUtil.joinParam(url, ParamName.loginId, loginId); - url = SaFoxUtil.joinParam(url, ParamName.timestamp, timestamp); - url = SaFoxUtil.joinParam(url, ParamName.nonce, nonce); - url = SaFoxUtil.joinParam(url, ParamName.sign, sign); + url = SaFoxUtil.joinParam(url, paramName.loginId, loginId); + url = SaFoxUtil.joinParam(url, paramName.timestamp, timestamp); + url = SaFoxUtil.joinParam(url, paramName.nonce, nonce); + url = SaFoxUtil.joinParam(url, paramName.sign, sign); return url; } @@ -471,10 +509,10 @@ public class SaSsoTemplate { public void checkSign(SaRequest req) { // 参数签名、账号id、时间戳、随机字符串 - String sign = req.getParamNotNull(ParamName.sign); - String loginId = req.getParamNotNull(ParamName.loginId); - String timestamp = req.getParamNotNull(ParamName.timestamp); - String nonce = req.getParamNotNull(ParamName.nonce); + String sign = req.getParamNotNull(paramName.sign); + String loginId = req.getParamNotNull(paramName.loginId); + String timestamp = req.getParamNotNull(paramName.timestamp); + String nonce = req.getParamNotNull(paramName.nonce); // 校验时间戳 checkTimestamp(Long.valueOf(timestamp)); diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoUtil.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoUtil.java index cda21d75..43e6aadc 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoUtil.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoUtil.java @@ -1,7 +1,6 @@ package cn.dev33.satoken.sso; import cn.dev33.satoken.context.model.SaRequest; -import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; /** @@ -14,7 +13,7 @@ public class SaSsoUtil { /** * 底层 SaSsoTemplate 对象 */ - public static SaSsoTemplate saSsoTemplate = new SaSsoTemplate(StpUtil.stpLogic); + public static SaSsoTemplate ssoTemplate = new SaSsoTemplate(); // ---------------------- Ticket 操作 ---------------------- @@ -25,7 +24,7 @@ public class SaSsoUtil { * @return Ticket码 */ public static String createTicket(Object loginId) { - return saSsoTemplate.createTicket(loginId); + return ssoTemplate.createTicket(loginId); } /** @@ -33,7 +32,7 @@ public class SaSsoUtil { * @param ticket Ticket码 */ public static void deleteTicket(String ticket) { - saSsoTemplate.deleteTicket(ticket); + ssoTemplate.deleteTicket(ticket); } /** @@ -41,7 +40,7 @@ public class SaSsoUtil { * @param loginId 账号id */ public static void deleteTicketIndex(Object loginId) { - saSsoTemplate.deleteTicketIndex(loginId); + ssoTemplate.deleteTicketIndex(loginId); } /** @@ -50,7 +49,7 @@ public class SaSsoUtil { * @return 账号id */ public static Object getLoginId(String ticket) { - return saSsoTemplate.getLoginId(ticket); + return ssoTemplate.getLoginId(ticket); } /** @@ -61,7 +60,7 @@ public class SaSsoUtil { * @return 账号id */ public static T getLoginId(String ticket, Class cs) { - return saSsoTemplate.getLoginId(ticket, cs); + return ssoTemplate.getLoginId(ticket, cs); } /** @@ -70,7 +69,7 @@ public class SaSsoUtil { * @return 账号id */ public static Object checkTicket(String ticket) { - return saSsoTemplate.checkTicket(ticket); + return ssoTemplate.checkTicket(ticket); } /** @@ -78,7 +77,7 @@ public class SaSsoUtil { * @return see note */ public static String getAllowUrl() { - return saSsoTemplate.getAllowUrl(); + return ssoTemplate.getAllowUrl(); } /** @@ -86,7 +85,7 @@ public class SaSsoUtil { * @param url 下放ticket的url地址 */ public static void checkRedirectUrl(String url) { - saSsoTemplate.checkRedirectUrl(url); + ssoTemplate.checkRedirectUrl(url); } @@ -99,7 +98,7 @@ public class SaSsoUtil { * @return 构建完毕的URL */ public static String buildCheckTicketUrl(String ticket, String ssoLogoutCallUrl) { - return saSsoTemplate.buildCheckTicketUrl(ticket, ssoLogoutCallUrl); + return ssoTemplate.buildCheckTicketUrl(ticket, ssoLogoutCallUrl); } /** @@ -108,7 +107,7 @@ public class SaSsoUtil { * @param sloCallbackUrl 单点注销时的回调URL */ public static void registerSloCallbackUrl(Object loginId, String sloCallbackUrl) { - saSsoTemplate.registerSloCallbackUrl(loginId, sloCallbackUrl); + ssoTemplate.registerSloCallbackUrl(loginId, sloCallbackUrl); } /** @@ -117,7 +116,7 @@ public class SaSsoUtil { * @return 单点注销URL */ public static String buildSloUrl(Object loginId) { - return saSsoTemplate.buildSloUrl(loginId); + return ssoTemplate.buildSloUrl(loginId); } /** @@ -125,7 +124,7 @@ public class SaSsoUtil { * @param loginId 指定账号 */ public static void ssoLogout(Object loginId) { - saSsoTemplate.ssoLogout(loginId); + ssoTemplate.ssoLogout(loginId); } /** @@ -134,7 +133,7 @@ public class SaSsoUtil { * @return 账号资料 */ public static Object getUserinfo(Object loginId) { - return saSsoTemplate.getUserinfo(loginId); + return ssoTemplate.getUserinfo(loginId); } @@ -147,7 +146,7 @@ public class SaSsoUtil { * @return [SSO-Server端-认证地址 ] */ public static String buildServerAuthUrl(String clientLoginUrl, String back) { - return saSsoTemplate.buildServerAuthUrl(clientLoginUrl, back); + return ssoTemplate.buildServerAuthUrl(clientLoginUrl, back); } /** @@ -157,7 +156,7 @@ public class SaSsoUtil { * @return see note */ public static String buildRedirectUrl(Object loginId, String redirect) { - return saSsoTemplate.buildRedirectUrl(loginId, redirect); + return ssoTemplate.buildRedirectUrl(loginId, redirect); } /** @@ -166,7 +165,7 @@ public class SaSsoUtil { * @return Server端 账号资料查询地址 */ public static String buildUserinfoUrl(Object loginId) { - return saSsoTemplate.buildUserinfoUrl(loginId); + return ssoTemplate.buildUserinfoUrl(loginId); } @@ -178,7 +177,7 @@ public class SaSsoUtil { * @return 返回的结果 */ public static SaResult request(String url) { - return saSsoTemplate.request(url); + return ssoTemplate.request(url); } /** @@ -187,7 +186,7 @@ public class SaSsoUtil { */ @Deprecated public static void checkSecretkey(String secretkey) { - saSsoTemplate.checkSecretkey(secretkey); + ssoTemplate.checkSecretkey(secretkey); } /** @@ -199,7 +198,7 @@ public class SaSsoUtil { * @return 签名 */ public static String getSign(Object loginId, String timestamp, String nonce, String secretkey) { - return saSsoTemplate.getSign(loginId, timestamp, nonce, secretkey); + return ssoTemplate.getSign(loginId, timestamp, nonce, secretkey); } /** @@ -209,7 +208,7 @@ public class SaSsoUtil { * @return 加工后的url */ public static String addSignParams(String url, Object loginId) { - return saSsoTemplate.addSignParams(url, loginId); + return ssoTemplate.addSignParams(url, loginId); } /** @@ -217,7 +216,7 @@ public class SaSsoUtil { * @param req request */ public static void checkSign(SaRequest req) { - saSsoTemplate.checkSign(req); + ssoTemplate.checkSign(req); } /** @@ -225,7 +224,7 @@ public class SaSsoUtil { * @param timestamp 时间戳 */ public static void checkTimestamp(long timestamp) { - saSsoTemplate.checkTimestamp(timestamp); + ssoTemplate.checkTimestamp(timestamp); } } diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java new file mode 100644 index 00000000..41e83ed7 --- /dev/null +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ApiName.java @@ -0,0 +1,79 @@ +package cn.dev33.satoken.sso.name; + +/** + * SSO 模块所有 API 路由名称定义 + * + * @author kong + * @since 2022-10-25 + */ +public class ApiName { + + /** SSO-Server端:授权地址 */ + public String ssoAuth = "/sso/auth"; + + /** SSO-Server端:RestAPI 登录接口 */ + public String ssoDoLogin = "/sso/doLogin"; + + /** SSO-Server端:校验ticket 获取账号id */ + public String ssoCheckTicket = "/sso/checkTicket"; + + /** SSO-Server端:获取userinfo */ + public String ssoUserinfo = "/sso/userinfo"; + + /** SSO-Server端:单点注销地址 */ + public String ssoSignout = "/sso/signout"; + + /** SSO-Client端:登录地址 */ + public String ssoLogin = "/sso/login"; + + /** SSO-Client端:单点注销地址 */ + public String ssoLogout = "/sso/logout"; + + /** SSO-Client端:单点注销的回调 */ + public String ssoLogoutCall = "/sso/logoutCall"; + + /** + * 批量修改path,新增固定前缀 + * @param prefix / + * @return 对象自身 + */ + public ApiName addPrefix(String prefix) { + this.ssoAuth = prefix + this.ssoAuth; + this.ssoDoLogin = prefix + this.ssoDoLogin; + this.ssoCheckTicket = prefix + this.ssoCheckTicket; + this.ssoUserinfo = prefix + this.ssoUserinfo; + this.ssoSignout = prefix + this.ssoSignout; + this.ssoLogin = prefix + this.ssoLogin; + this.ssoLogout = prefix + this.ssoLogout; + this.ssoLogoutCall = prefix + this.ssoLogoutCall; + return this; + } + + /** + * 批量修改path,替换掉 /sso 固定前缀 + * @param prefix / + * @return 对象自身 + */ + public ApiName replacePrefix(String prefix) { + String oldPrefix = "/sso"; + this.ssoAuth = this.ssoAuth.replaceFirst(oldPrefix, prefix); + this.ssoDoLogin = this.ssoDoLogin.replaceFirst(oldPrefix, prefix); + this.ssoCheckTicket = this.ssoCheckTicket.replaceFirst(oldPrefix, prefix); + this.ssoUserinfo = this.ssoUserinfo.replaceFirst(oldPrefix, prefix); + this.ssoSignout = this.ssoSignout.replaceFirst(oldPrefix, prefix); + this.ssoLogin = this.ssoLogin.replaceFirst(oldPrefix, prefix); + this.ssoLogout = this.ssoLogout.replaceFirst(oldPrefix, prefix); + this.ssoLogoutCall = this.ssoLogoutCall.replaceFirst(oldPrefix, prefix); + return this; + } + + + @Override + public String toString() { + return "ApiName [ssoAuth=" + ssoAuth + ", ssoDoLogin=" + ssoDoLogin + ", ssoCheckTicket=" + ssoCheckTicket + + ", ssoUserinfo=" + ssoUserinfo + ", ssoSignout=" + ssoSignout + ", ssoLogin=" + ssoLogin + + ", ssoLogout=" + ssoLogout + ", ssoLogoutCall=" + ssoLogoutCall + "]"; + } + + +} diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java new file mode 100644 index 00000000..d48bd898 --- /dev/null +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/name/ParamName.java @@ -0,0 +1,39 @@ +package cn.dev33.satoken.sso.name; + +/** + * SSO 模块所有参数名称定义 + * + * @author kong + * @since 2022-10-25 + */ +public class ParamName { + + /** redirect参数名称 */ + public String redirect = "redirect"; + + /** ticket参数名称 */ + public String ticket = "ticket"; + + /** back参数名称 */ + public String back = "back"; + + /** mode参数名称 */ + public String mode = "mode"; + + /** loginId参数名称 */ + public String loginId = "loginId"; + + /** secretkey参数名称 */ + public String secretkey = "secretkey"; + + /** Client端单点注销时-回调URL 参数名称 */ + public String ssoLogoutCall = "ssoLogoutCall"; + + public String name = "name"; + public String pwd = "pwd"; + + public String timestamp = "timestamp"; + public String nonce = "nonce"; + public String sign = "sign"; + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/SaSsoBeanInject.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/SaSsoBeanInject.java index 7f2c4785..baf7926e 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/SaSsoBeanInject.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/SaSsoBeanInject.java @@ -34,7 +34,7 @@ public class SaSsoBeanInject { */ @Autowired(required = false) public void setSaSsoTemplate(SaSsoTemplate saSsoTemplate) { - SaSsoUtil.saSsoTemplate = saSsoTemplate; + SaSsoUtil.ssoTemplate = saSsoTemplate; } } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java index 3adbb3d5..daf94207 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java @@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import cn.dev33.satoken.config.SaSsoConfig; import cn.dev33.satoken.sso.SaSsoManager; +import cn.dev33.satoken.sso.SaSsoProcessor; import cn.dev33.satoken.sso.SaSsoTemplate; import cn.dev33.satoken.sso.SaSsoUtil; @@ -30,11 +31,12 @@ public class SaSsoBeanInject { /** * 注入 Sa-Token-SSO 单点登录模块 Bean * - * @param saSsoTemplate saSsoTemplate对象 + * @param ssoTemplate saSsoTemplate对象 */ @Autowired(required = false) - public void setSaSsoTemplate(SaSsoTemplate saSsoTemplate) { - SaSsoUtil.saSsoTemplate = saSsoTemplate; + public void setSaSsoTemplate(SaSsoTemplate ssoTemplate) { + SaSsoUtil.ssoTemplate = ssoTemplate; + SaSsoProcessor.instance.ssoTemplate = ssoTemplate; } }