From 35cf52c684367acf7fddd4f74b96bfcae29ae999 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Thu, 26 Aug 2021 23:17:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=8D=95=E7=82=B9=E7=99=BB?= =?UTF-8?q?=E5=BD=95demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mvn clean.bat | 8 + .../sa-token-demo-sso1-client/.gitignore | 12 ++ .../sa-token-demo-sso1-client/pom.xml | 60 +++++++ .../java/com/pj/SaSsoClientApplication.java | 19 ++ .../java/com/pj/sso/SsoClientController.java | 39 +++++ .../src/main/resources/application.yml | 40 +++++ .../sa-token-demo-sso1-server/.gitignore | 12 ++ .../sa-token-demo-sso1-server/pom.xml | 57 ++++++ .../java/com/pj/SaSsoServerApplication.java | 19 ++ .../java/com/pj/sso/SsoServerController.java | 62 +++++++ .../src/main/resources/application.yml | 38 ++++ .../main/resources/static/sa-res/login.css | 59 +++++++ .../src/main/resources/static/sa-res/login.js | 65 +++++++ .../main/resources/templates/sa-login.html | 45 +++++ .../main/java/com/pj/SaSsoApplication.java | 22 ++- .../main/java/com/pj/sso/SsoController.java | 13 +- .../src/main/java/com/pj/util/AjaxJson.java | 162 ------------------ sa-token-doc/doc/sso/readme.md | 24 +-- sa-token-doc/doc/sso/sso-type1.md | 78 +++++++-- sa-token-doc/doc/sso/sso-type2.md | 7 +- sa-token-doc/doc/start/download.md | 4 +- 21 files changed, 644 insertions(+), 201 deletions(-) create mode 100644 sa-token-demo/sa-token-demo-sso1-client/.gitignore create mode 100644 sa-token-demo/sa-token-demo-sso1-client/pom.xml create mode 100644 sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSsoClientApplication.java create mode 100644 sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java create mode 100644 sa-token-demo/sa-token-demo-sso1-client/src/main/resources/application.yml create mode 100644 sa-token-demo/sa-token-demo-sso1-server/.gitignore create mode 100644 sa-token-demo/sa-token-demo-sso1-server/pom.xml create mode 100644 sa-token-demo/sa-token-demo-sso1-server/src/main/java/com/pj/SaSsoServerApplication.java create mode 100644 sa-token-demo/sa-token-demo-sso1-server/src/main/java/com/pj/sso/SsoServerController.java create mode 100644 sa-token-demo/sa-token-demo-sso1-server/src/main/resources/application.yml create mode 100644 sa-token-demo/sa-token-demo-sso1-server/src/main/resources/static/sa-res/login.css create mode 100644 sa-token-demo/sa-token-demo-sso1-server/src/main/resources/static/sa-res/login.js create mode 100644 sa-token-demo/sa-token-demo-sso1-server/src/main/resources/templates/sa-login.html delete mode 100644 sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/util/AjaxJson.java diff --git a/mvn clean.bat b/mvn clean.bat index 6c5badfc..3714ac9b 100644 --- a/mvn clean.bat +++ b/mvn clean.bat @@ -41,6 +41,14 @@ cd sa-token-demo-sso1 call mvn clean cd .. +cd sa-token-demo-sso1-server +call mvn clean +cd .. + +cd sa-token-demo-sso1-client +call mvn clean +cd .. + cd sa-token-demo-sso2-server call mvn clean cd .. diff --git a/sa-token-demo/sa-token-demo-sso1-client/.gitignore b/sa-token-demo/sa-token-demo-sso1-client/.gitignore new file mode 100644 index 00000000..99a6e767 --- /dev/null +++ b/sa-token-demo/sa-token-demo-sso1-client/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.idea/ + +.factorypath \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-sso1-client/pom.xml b/sa-token-demo/sa-token-demo-sso1-client/pom.xml new file mode 100644 index 00000000..63ab9b45 --- /dev/null +++ b/sa-token-demo/sa-token-demo-sso1-client/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + cn.dev33 + sa-token-demo-sso1-client + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.RELEASE + + + + + + 1.25.0 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + cn.dev33 + sa-token-spring-boot-starter + ${sa-token-version} + + + + + cn.dev33 + sa-token-dao-redis-jackson + ${sa-token-version} + + + + + org.apache.commons + commons-pool2 + + + + + cn.dev33 + sa-token-alone-redis + ${sa-token-version} + + + + + + \ No newline at end of file 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/SaSsoClientApplication.java new file mode 100644 index 00000000..48a0c842 --- /dev/null +++ b/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/SaSsoClientApplication.java @@ -0,0 +1,19 @@ +package com.pj; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * SSO模式一,Client端 Demo + * @author kong + * + */ +@SpringBootApplication +public class SaSsoClientApplication { + + public static void main(String[] args) { + SpringApplication.run(SaSsoClientApplication.class, args); + System.out.println("\nSa-Token-SSO Client端启动成功"); + } + +} \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java b/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java new file mode 100644 index 00000000..d4a87d3f --- /dev/null +++ b/sa-token-demo/sa-token-demo-sso1-client/src/main/java/com/pj/sso/SsoClientController.java @@ -0,0 +1,39 @@ +package com.pj.sso; + +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.SaManager; +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; + +/** + * Sa-Token-SSO Client端 Controller + * @author kong + */ +@RestController +public class SsoClientController { + + /* + * SSO-Client端:首页 + */ + @RequestMapping("/") + public String index() { + String authUrl = SaManager.getConfig().getSso().getAuthUrl(); + String solUrl = SaManager.getConfig().getSso().getSloUrl(); + String str = "

Sa-Token SSO-Client 应用端

" + + "

当前会话是否登录:" + StpUtil.isLogin() + "

" + + "

+ + + Sa-SSO-Server 认证中心-登录 + + + + + + +

+
+
+
+ +
+ +
+ This page is provided by Sa-Token-SSO +
+
+ + + + + + + + diff --git a/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/SaSsoApplication.java b/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/SaSsoApplication.java index c80e20a4..c8c33aa0 100644 --- a/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/SaSsoApplication.java +++ b/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/SaSsoApplication.java @@ -8,9 +8,29 @@ import cn.dev33.satoken.SaManager; @SpringBootApplication public class SaSsoApplication { + /* + 此 demo 意在使用最少的代码演示一下SSO模式一的认证原理 + 1、改hosts(C:\windows\system32\drivers\etc\hosts) + 127.0.0.1 sso.stp.com + 127.0.0.1 s1.stp.com + 127.0.0.1 s2.stp.com + 127.0.0.1 s3.stp.com + 2、运行项目 + 启动 SaSsoApplication + 3、浏览器访问 + http://s1.stp.com:8081/sso/isLogin + http://s2.stp.com:8081/sso/isLogin + http://s3.stp.com:8081/sso/isLogin + 均显示未登录 + 4、然后访问任意节点的登录接口: + http://s1.stp.com:8081/sso/doLogin + 5、重复步骤3,刷新三个地址 + 均显示已登录 + */ + public static void main(String[] args) { SpringApplication.run(SaSsoApplication.class, args); System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); } - + } \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/sso/SsoController.java b/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/sso/SsoController.java index d5e59d57..7ace8472 100644 --- a/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/sso/SsoController.java +++ b/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/sso/SsoController.java @@ -4,9 +4,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.pj.util.AjaxJson; - import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; /** * 测试: 同域单点登录 @@ -15,21 +14,21 @@ import cn.dev33.satoken.stp.StpUtil; @RestController @RequestMapping("/sso/") public class SsoController { - + // 测试:进行登录 @RequestMapping("doLogin") - public AjaxJson doLogin(@RequestParam(defaultValue = "10001") String id) { + public SaResult doLogin(@RequestParam(defaultValue = "10001") String id) { System.out.println("---------------- 进行登录 "); StpUtil.login(id); - return AjaxJson.getSuccess("登录成功: " + id); + return SaResult.ok("登录成功: " + id); } // 测试:是否登录 @RequestMapping("isLogin") - public AjaxJson isLogin() { + public SaResult isLogin() { System.out.println("---------------- 是否登录 "); boolean isLogin = StpUtil.isLogin(); - return AjaxJson.getSuccess("是否登录: " + isLogin); + return SaResult.ok("是否登录: " + isLogin); } } diff --git a/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/util/AjaxJson.java b/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/util/AjaxJson.java deleted file mode 100644 index 768d0578..00000000 --- a/sa-token-demo/sa-token-demo-sso1/src/main/java/com/pj/util/AjaxJson.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.pj.util; - -import java.io.Serializable; -import java.util.List; - - -/** - * ajax请求返回Json格式数据的封装 - */ -public class AjaxJson implements Serializable{ - - private static final long serialVersionUID = 1L; // 序列化版本号 - - public static final int CODE_SUCCESS = 200; // 成功状态码 - public static final int CODE_ERROR = 500; // 错误状态码 - public static final int CODE_WARNING = 501; // 警告状态码 - public static final int CODE_NOT_JUR = 403; // 无权限状态码 - public static final int CODE_NOT_LOGIN = 401; // 未登录状态码 - public static final int CODE_INVALID_REQUEST = 400; // 无效请求状态码 - - public int code; // 状态码 - public String msg; // 描述信息 - public Object data; // 携带对象 - public Long dataCount; // 数据总数,用于分页 - - /** - * 返回code - * @return - */ - public int getCode() { - return this.code; - } - - /** - * 给msg赋值,连缀风格 - */ - public AjaxJson setMsg(String msg) { - this.msg = msg; - return this; - } - public String getMsg() { - return this.msg; - } - - /** - * 给data赋值,连缀风格 - */ - public AjaxJson setData(Object data) { - this.data = data; - return this; - } - - /** - * 将data还原为指定类型并返回 - */ - @SuppressWarnings("unchecked") - public T getData(Class cs) { - return (T) data; - } - - // ============================ 构建 ================================== - - public AjaxJson(int code, String msg, Object data, Long dataCount) { - this.code = code; - this.msg = msg; - this.data = data; - this.dataCount = dataCount; - } - - // 返回成功 - public static AjaxJson getSuccess() { - return new AjaxJson(CODE_SUCCESS, "ok", null, null); - } - public static AjaxJson getSuccess(String msg) { - return new AjaxJson(CODE_SUCCESS, msg, null, null); - } - public static AjaxJson getSuccess(String msg, Object data) { - return new AjaxJson(CODE_SUCCESS, msg, data, null); - } - public static AjaxJson getSuccessData(Object data) { - return new AjaxJson(CODE_SUCCESS, "ok", data, null); - } - public static AjaxJson getSuccessArray(Object... data) { - return new AjaxJson(CODE_SUCCESS, "ok", data, null); - } - - // 返回失败 - public static AjaxJson getError() { - return new AjaxJson(CODE_ERROR, "error", null, null); - } - public static AjaxJson getError(String msg) { - return new AjaxJson(CODE_ERROR, msg, null, null); - } - - // 返回警告 - public static AjaxJson getWarning() { - return new AjaxJson(CODE_ERROR, "warning", null, null); - } - public static AjaxJson getWarning(String msg) { - return new AjaxJson(CODE_WARNING, msg, null, null); - } - - // 返回未登录 - public static AjaxJson getNotLogin() { - return new AjaxJson(CODE_NOT_LOGIN, "未登录,请登录后再次访问", null, null); - } - - // 返回没有权限的 - public static AjaxJson getNotJur(String msg) { - return new AjaxJson(CODE_NOT_JUR, msg, null, null); - } - - // 返回一个自定义状态码的 - public static AjaxJson get(int code, String msg){ - return new AjaxJson(code, msg, null, null); - } - - // 返回分页和数据的 - public static AjaxJson getPageData(Long dataCount, Object data){ - return new AjaxJson(CODE_SUCCESS, "ok", data, dataCount); - } - - // 返回,根据受影响行数的(大于0=ok,小于0=error) - public static AjaxJson getByLine(int line){ - if(line > 0){ - return getSuccess("ok", line); - } - return getError("error").setData(line); - } - - // 返回,根据布尔值来确定最终结果的 (true=ok,false=error) - public static AjaxJson getByBoolean(boolean b){ - return b ? getSuccess("ok") : getError("error"); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @SuppressWarnings("rawtypes") - @Override - public String toString() { - String data_string = null; - if(data == null){ - - } else if(data instanceof List){ - data_string = "List(length=" + ((List)data).size() + ")"; - } else { - data_string = data.toString(); - } - return "{" - + "\"code\": " + this.getCode() - + ", \"msg\": \"" + this.getMsg() + "\"" - + ", \"data\": " + data_string - + ", \"dataCount\": " + dataCount - + "}"; - } - - - - - -} diff --git a/sa-token-doc/doc/sso/readme.md b/sa-token-doc/doc/sso/readme.md index e1b5bc66..076fc699 100644 --- a/sa-token-doc/doc/sso/readme.md +++ b/sa-token-doc/doc/sso/readme.md @@ -1,11 +1,13 @@ # Sa-Token-SSO 单点登录模块 +凡是稍微上点规模的系统,统一认证中心都是绕不过去的槛。而单点登录——便是我们搭建统一认证中心的关键。 + --- ### 什么是单点登录?解决什么问题? 举个场景,假设我们的系统被切割为N个部分:商城、论坛、直播、社交…… 如果用户每访问一个模块都要登录一次,那么用户将会疯掉, -为了优化用户体验,我们急需一套机制将这N个系统的认证授权互通共享,让用户在一个系统登录之后,便可以畅通无阻的访问其它所有系统 +为了优化用户体验,我们急需一套机制将这N个系统的认证授权互通共享,让用户在一个系统登录之后,便可以畅通无阻的访问其它所有系统。 单点登录——就是为了解决这个问题而生! @@ -13,19 +15,19 @@ ### 架构选型 -对于单点登录,网上教程大多以CAS模式为主,其实对于不同的系统架构,实现单点登录的步骤也大为不同,Sa-Token由简入难将其划分为三种模式: +对于单点登录,网上教程大多以CAS模式为主,其实对于不同的系统架构,实现单点登录的步骤也大为不同,Sa-Token 由简入难将其划分为三种模式: -| 系统架构 | 采用模式 | 简介 | 文档链接 | -| :-------- | :-------- | :-------- | :-------- | -| 前端同域 + 后端同 Redis | 模式一 | 共享Cookie同步会话 | [文档](/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso1) | -| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso2-server) | -| 前端不同域 + 后端 不同Redis | 模式三 | Http请求获取会话 | [文档](/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso3-server) | +| 系统架构 | 采用模式 | 简介 | 文档链接 | +| :-------- | :-------- | :-------- | :-------- | +| 前端同域 + 后端同 Redis | 模式一 | 共享 Cookie 同步会话 | [文档](/sso/sso-type1)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso1) | +| 前端不同域 + 后端同 Redis | 模式二 | URL重定向传播会话 | [文档](/sso/sso-type2)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso2-server) | +| 前端不同域 + 后端不同 Redis | 模式三 | Http请求获取会话 | [文档](/sso/sso-type3)、[示例](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-sso3-server) | -1. 前端同域:就是指多个系统可以部署在同一个主域名之下,比如:`c1.domain.com`、`c2.domain.com`、`c3.domain.com` -2. 后端同Redis:就是指多个系统可以连接同一个Redis,其它的缓存数据中心亦可。PS:这里并不需要把所有项目的数据都放在同一个Redis中,Sa-Token提供了 **`[权限缓存与业务缓存分离]`** 的解决方案,详情戳:[Alone独立Redis插件](http://sa-token.dev33.cn/doc/index.html#/plugin/alone-redis) -3. 如果既无法做到前端同域,也无法做到后端同Redis,那么只能走模式三,Http请求获取会话(Sa-Token对SSO提供了完整的封装,你只需要按照示例从文档上复制几段代码便可以轻松集成) -4. 技术选型一定要根据系统架构对症下药,切不可胡乱选择 +1. 前端同域:就是指多个系统可以部署在同一个主域名之下,比如:`c1.domain.com`、`c2.domain.com`、`c3.domain.com`。 +2. 后端同Redis:就是指多个系统可以连接同一个Redis,其它的缓存数据中心亦可。PS:这里并不需要把所有项目的数据都放在同一个Redis中,Sa-Token提供了 **`[权限缓存与业务缓存分离]`** 的解决方案,详情戳:[Alone独立Redis插件](http://sa-token.dev33.cn/doc/index.html#/plugin/alone-redis)。 +3. 如果既无法做到前端同域,也无法做到后端同Redis,那么只能走模式三,Http请求获取会话(Sa-Token对SSO提供了完整的封装,你只需要按照示例从文档上复制几段代码便可以轻松集成)。 +4. 技术选型一定要根据系统架构对症下药,切不可胡乱选择。 ### Sa-Token-SSO 特性 diff --git a/sa-token-doc/doc/sso/sso-type1.md b/sa-token-doc/doc/sso/sso-type1.md index dfa8cbbc..06065ff1 100644 --- a/sa-token-doc/doc/sso/sso-type1.md +++ b/sa-token-doc/doc/sso/sso-type1.md @@ -1,29 +1,29 @@ # SSO模式一 共享Cookie同步会话 -如果我们的多个系统可以做到:前端同域、后端同Redis,那么便可以使用 **`[共享Cookie同步会话]`** 的方式做到单点登录 +如果我们的多个系统可以做到:前端同域、后端同Redis,那么便可以使用 **`[共享Cookie同步会话]`** 的方式做到单点登录。 --- ### 0、解决思路? 首先我们分析一下多个系统之间,为什么无法同步登录状态? -1. 前端的`Token`无法在多个系统下共享 -2. 后端的`Session`无法在多个系统间共享 +1. 前端的`Token`无法在多个系统下共享。 +2. 后端的`Session`无法在多个系统间共享。 所以单点登录第一招,就是对症下药: -1. 使用`共享Cookie`来解决Token共享问题 -2. 使用`Redis`来解决Session共享问题 +1. 使用`共享Cookie`来解决Token共享问题。 +2. 使用`Redis`来解决Session共享问题。 -所谓共享Cookie,就是主域名Cookie在二级域名下的共享,举个例子:写在父域名`stp.com`下的Cookie,在`s1.stp.com`、`s2.stp.com`等子域名都是可以共享访问的 +所谓共享Cookie,就是主域名Cookie在二级域名下的共享,举个例子:写在父域名`stp.com`下的Cookie,在`s1.stp.com`、`s2.stp.com`等子域名都是可以共享访问的。 -而共享Redis,并不需要我们把所有项目的数据都放在同一个Redis中,Sa-Token提供了 **[权限缓存与业务缓存分离]** 的解决方案,详情戳:[Alone独立Redis插件](/plugin/alone-redis) +而共享Redis,并不需要我们把所有项目的数据都放在同一个Redis中,Sa-Token提供了 **[权限缓存与业务缓存分离]** 的解决方案,详情戳:[Alone独立Redis插件](/plugin/alone-redis)。 -> PS:这里建议不要用B项目去连接A项目的Redis,也不要A项目连接B项目的Redis,而是抽离出一个单独的 SSO-Redis,A 和 B 一起连接这个 SSO-Redis + -OK,所有理论就绪,下面开始实战 +OK,所有理论就绪,下面开始实战: -> Sa-Token整合同域单点登录非常简单,相比于正常的登录,你只需增加配置 `sa-token.cookie-domain=xxx.com` 指定一下Cookie写入时的父级域名即可
-> 整合示例在官方仓库的 `/sa-token-demo/sa-token-demo-sso1/`,如遇到难点可结合源码进行测试学习 +> Sa-Token整合同域单点登录非常简单,相比于正常的登录,你只需增加配置 `sa-token.cookie-domain=xxx.com` 指定一下Cookie写入时的父级域名即可。
+> 整合示例在官方仓库的 `/sa-token-demo/sa-token-demo-sso1/`,如遇到难点可结合源码进行测试学习。 @@ -31,13 +31,17 @@ OK,所有理论就绪,下面开始实战 首先修改hosts文件`(C:\windows\system32\drivers\etc\hosts)`,添加以下IP映射,方便我们进行测试: ``` url +127.0.0.1 sso.stp.com 127.0.0.1 s1.stp.com 127.0.0.1 s2.stp.com 127.0.0.1 s3.stp.com ``` +其中:`sso.stp.com`为统一认证地址,当用户在其它 Client 端发起登录请求时,均将其重定向至认证中心,待到登录成功之后再原路返回到 Client 端。 + + ### 2、指定Cookie的作用域 -在`s1.stp.com`访问服务器,其Cookie也只能写入到`s1.stp.com`下,为了将Cookie写入到其父级域名`stp.com`下,我们需要新增配置: +在`s1.stp.com`访问服务器,其Cookie也只能写入到`s1.stp.com`下,为了将Cookie写入到其父级域名`stp.com`下,我们需要新增配置: ``` yml sa-token: # 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie @@ -57,18 +61,18 @@ public class SsoController { // 测试:进行登录 @RequestMapping("doLogin") - public AjaxJson doLogin(@RequestParam(defaultValue = "10001") String id) { + public SaResult doLogin(@RequestParam(defaultValue = "10001") String id) { System.out.println("---------------- 进行登录 "); StpUtil.login(id); - return AjaxJson.getSuccess("登录成功: " + id); + return SaResult.ok("登录成功: " + id); } // 测试:是否登录 @RequestMapping("isLogin") - public AjaxJson isLogin() { + public SaResult isLogin() { System.out.println("---------------- 是否登录 "); boolean isLogin = StpUtil.isLogin(); - return AjaxJson.getSuccess("是否登录: " + isLogin); + return SaResult.ok("是否登录: " + isLogin); } } @@ -104,10 +108,48 @@ public class SaSsoApplication { ![sso-type1-yd.png](https://oss.dev33.cn/sa-token/doc/sso/sso-type1-yd.png 's-w-sh') -测试完毕 +测试完毕! -### 5、跨域模式下的解决方案 +### 5、搭建统一认证中心 + +上面的示例,我们简单的演示了SSO模式一的认证原理。 + +当然,在实际的正式项目中,我们肯定不会每个系统都内置一个登录接口,一般的做法是搭建一个独立的SSO认证中心,我们所有 Client 端的登录请求都会被重定向至认证中心, +待到登录成功之后再原路返回到 Client 端。 + +我们可以运行一下官方仓库的示例,里面有制作好的登录页面 + +> 下载官方示例,依次运行: +> - `/sa-token-demo/sa-token-demo-sso1-server/` +> - `/sa-token-demo/sa-token-demo-sso1-client/` + + +访问三个应用端: +- [http://s1.stp.com:9001/](http://s1.stp.com:9001/) +- [http://s2.stp.com:9001/](http://s2.stp.com:9001/) +- [http://s3.stp.com:9001/](http://s3.stp.com:9001/) + +均返回: + +![sso1--index.png](https://oss.dev33.cn/sa-token/doc/sso/sso1--index.png 's-w-sh') + +然后点击登录,被重定向至SSO认证中心: + +![sso1--login-page.png](https://oss.dev33.cn/sa-token/doc/sso/sso1--login-page.png 's-w-sh') + +输入默认测试账号:`sa / 123456`,点击登录 + +![sso1-login-ok.png](https://oss.dev33.cn/sa-token/doc/sso/sso1-login-ok.png 's-w-sh') + +刷新另外两个Client端,均显示已登录 + +![sso1-login-ok2.png](https://oss.dev33.cn/sa-token/doc/sso/sso1-login-ok2.png 's-w-sh') + +测试完成 + + +### 6、跨域模式下的解决方案 如上,我们使用极其简单的步骤实现了同域下的单点登录,聪明如你😏,马上想到了这种模式有着一个不小的限制: diff --git a/sa-token-doc/doc/sso/sso-type2.md b/sa-token-doc/doc/sso/sso-type2.md index 7d9f9bf0..ba57f081 100644 --- a/sa-token-doc/doc/sso/sso-type2.md +++ b/sa-token-doc/doc/sso/sso-type2.md @@ -306,7 +306,12 @@ public class SaSsoClientApplication { 以上示例,虽然完整的复现了单点登录的过程,但是页面还是有些简陋,我们可以运行一下官方仓库的示例,里面有制作好的登录页面 -> 下载官方示例,依次运行 `/sa-token-demo/sa-token-demo-sso-client/` 和 `/sa-token-demo/sa-token-demo-sso-server/`,访问:[http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/) +> 下载官方示例,依次运行: +> - `/sa-token-demo/sa-token-demo-sso2-server/` +> - `/sa-token-demo/sa-token-demo-sso2-client/` +> +> 然后访问: +> - [http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/) ![sso-server-login-hua](https://oss.dev33.cn/sa-token/doc/sso/sso-server-login-hua.png 's-w-sh') diff --git a/sa-token-doc/doc/start/download.md b/sa-token-doc/doc/start/download.md index d193795d..5d849bd0 100644 --- a/sa-token-doc/doc/start/download.md +++ b/sa-token-doc/doc/start/download.md @@ -106,7 +106,9 @@ implementation 'cn.dev33:sa-token-core:${sa.top.version}' ├── sa-token-demo-solon // [示例] Sa-Token 集成 Solon ├── sa-token-demo-quick-login // [示例] Sa-Token 集成 quick-login 模块 ├── sa-token-demo-alone-redis // [示例] Sa-Token 集成 alone-redis 模块 - ├── sa-token-demo-sso1 // [示例] Sa-Token 集成 SSO单点登录-模式一 + ├── sa-token-demo-sso1 // [示例] Sa-Token 集成 SSO单点登录-模式一简单测试 + ├── sa-token-demo-sso1-server // [示例] Sa-Token 集成 SSO单点登录-模式一 认证中心 + ├── sa-token-demo-sso1-client // [示例] Sa-Token 集成 SSO单点登录-模式一 应用端 ├── sa-token-demo-sso2-server // [示例] Sa-Token 集成 SSO单点登录-模式二 认证中心 ├── sa-token-demo-sso2-client // [示例] Sa-Token 集成 SSO单点登录-模式二 应用端 ├── sa-token-demo-sso3-server // [示例] Sa-Token 集成 SSO单点登录-模式三 认证中心