mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
晚上单点登录文档
This commit is contained in:
parent
cf93324053
commit
bea2592dc9
@ -92,7 +92,7 @@ public interface SaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的url,例:http://xxx.com/?id=127
|
||||
* 返回当前请求的url,例:http://xxx.com/
|
||||
* @return see note
|
||||
*/
|
||||
public String getUrl();
|
||||
|
@ -1,18 +0,0 @@
|
||||
package com.pj.satoken;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* 继承Sa-Token行为Bean默认实现, 重写部分逻辑
|
||||
*/
|
||||
@Component
|
||||
public class MySaTokenAction extends SaTokenActionDefaultImpl {
|
||||
// 重写token生成策略
|
||||
@Override
|
||||
public String createToken(Object loginId, String loginType) {
|
||||
return SaFoxUtil.getRandomString(60); // 随机60位字符串
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@
|
||||
- [SSO模式一 共享Cookie同步会话](/sso/sso-type1)
|
||||
- [SSO模式二 URL重定向传播会话](/sso/sso-type2)
|
||||
- [SSO模式三 Http请求获取会话](/sso/sso-type3)
|
||||
- [SSO整合-常见问题总结](/sso/sso-cd)
|
||||
|
||||
- **OAuth2.0**
|
||||
- [OAuth2.0简述](/oauth2/readme)
|
||||
|
127
sa-token-doc/doc/sso/sso-cd.md
Normal file
127
sa-token-doc/doc/sso/sso-cd.md
Normal file
@ -0,0 +1,127 @@
|
||||
# Sa-Token-SSO整合-常见问题总结
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 一、何时引导用户去登录?
|
||||
|
||||
以下解决方案三选一:
|
||||
|
||||
##### 1.1、前端按钮跳转
|
||||
前端页面准备一个**`[登录]`**按钮,当用户点击按钮时,跳转到登录接口
|
||||
``` js
|
||||
<a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a>
|
||||
```
|
||||
|
||||
##### 1.2、后端拦截重定向
|
||||
在后端注册全局过滤器(或拦截器),拦截需要登录后才能访问的页面资源,将未登录的访问重定向至登录接口
|
||||
``` java
|
||||
/**
|
||||
* Sa-Token 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
/** 注册 [Sa-Token全局过滤器] */
|
||||
@Bean
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
.addInclude("/**")
|
||||
.addExclude("/sso/*", "/favicon.ico")
|
||||
.setAuth(r -> {
|
||||
if(StpUtil.isLogin() == false) {
|
||||
String back = SaFoxUtil.joinParam(SaHolder.getRequest().getUrl(), SpringMVCUtil.getRequest().getQueryString());
|
||||
SaHolder.getResponse().redirect("/sso/login?back=" + SaFoxUtil.encodeUrl(back));
|
||||
SaRouter.back();
|
||||
}
|
||||
})
|
||||
;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### 1.3、后端拦截 + 前端跳转
|
||||
首先,后端仍需要提供拦截,但是不直接引导用户重定向,而是返回未登录的提示信息
|
||||
``` java
|
||||
/**
|
||||
* Sa-Token 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
/** 注册 [Sa-Token全局过滤器] */
|
||||
@Bean
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
.addInclude("/**")
|
||||
.addExclude("/sso/*", "/favicon.ico")
|
||||
.setAuth(r -> {
|
||||
if(StpUtil.isLogin() == false) {
|
||||
// 与前端约定好,code=401时代表会话未登录
|
||||
SaRouter.back(SaResult.ok().setCode(401));
|
||||
}
|
||||
})
|
||||
;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
前端接受到返回结果 `code=401` 时,开始跳转至登录接口
|
||||
``` js
|
||||
if(res.code == 401) {
|
||||
location.href = '/sso/login?back=' + encodeURIComponent(location.href);
|
||||
}
|
||||
```
|
||||
|
||||
这种方案比较适合以 Ajax 访问的 RestAPI 接口重定向
|
||||
|
||||
|
||||
|
||||
|
||||
### 二、定制化开发
|
||||
|
||||
##### 2.1、如何自定义登录视图?
|
||||
- 方式一:在demo示例中直接更改页面代码
|
||||
- 方式二:在配置中配置登录视图地址
|
||||
|
||||
``` java
|
||||
cfg.sso
|
||||
// 配置:未登录时返回的View
|
||||
.setNotLoginView(() -> {
|
||||
return new ModelAndView("xxx.html");
|
||||
})
|
||||
```
|
||||
|
||||
##### 2.2、如何自定义登录API的接口?
|
||||
根据需求点选择解决方案:
|
||||
|
||||
**2.2.1、如果只是想在 setDoLoginHandle 函数里获取除 name、pwd 以外的参数?**
|
||||
``` java
|
||||
// 在任意代码处获取前端提交的参数
|
||||
String xxx = SaHolder.getRequest().getParam("xxx");
|
||||
```
|
||||
|
||||
**2.2.2、想完全自定义一个接口来接受前端登录请求?**
|
||||
``` java
|
||||
// 直接定义一个拦截路由为 `/sso/doLogin` 的接口即可
|
||||
@RequestMapping("/sso/doLogin")
|
||||
public SaResult ss(String name, String pwd) {
|
||||
System.out.println("------ 请求进入了自定义的API接口 ---------- ");
|
||||
if("sa".equals(name) && "123456".equals(pwd)) {
|
||||
StpUtil.login(10001);
|
||||
return SaResult.ok("登录成功!");
|
||||
}
|
||||
return SaResult.error("登录失败!");
|
||||
}
|
||||
```
|
||||
|
||||
**2.2.3、不想使用`/sso/doLogin`这个接口,想自定义一个API地址?**
|
||||
|
||||
答:直接在前端更改点击按钮时 Ajax 的请求地址即可
|
||||
|
||||
|
||||
### 三、常见疑问
|
||||
|
||||
##### 问:在模式一与模式二中,Client端 必须通过 Alone-Redis 插件来访问Redis吗?
|
||||
|
||||
答:不必须,只是推荐,权限缓存与业务缓存分离后会减少SSO-Redis的访问压力,且可以避免多个Client端的缓存读写冲突
|
||||
|
||||
|
@ -27,12 +27,21 @@
|
||||
|
||||
下面我们按照步骤依次完成上述过程
|
||||
|
||||
### 1、准备工作
|
||||
首先修改hosts文件`(C:\windows\system32\drivers\etc\hosts)`,添加以下IP映射,方便我们进行测试:
|
||||
``` url
|
||||
127.0.0.1 sa-sso-server.com
|
||||
127.0.0.1 sa-sso-client1.com
|
||||
127.0.0.1 sa-sso-client2.com
|
||||
127.0.0.1 sa-sso-client3.com
|
||||
```
|
||||
|
||||
### 1、搭建SSO-Server认证中心
|
||||
|
||||
### 2、搭建SSO-Server认证中心
|
||||
|
||||
> 搭建示例在官方仓库的 `/sa-token-demo/sa-token-demo-sso2-server/`,如遇到难点可结合源码进行测试学习
|
||||
|
||||
##### 1.1、创建SSO-Server端项目
|
||||
##### 2.1、创建SSO-Server端项目
|
||||
创建SpringBoot项目 `sa-token-demo-sso-server`(不会的同学自行百度或参考仓库示例),添加pom依赖:
|
||||
|
||||
``` xml
|
||||
@ -55,7 +64,7 @@
|
||||
</dependency>
|
||||
```
|
||||
|
||||
##### 1.2、创建SSO-Server端认证接口
|
||||
##### 2.2、创建SSO-Server端认证接口
|
||||
``` java
|
||||
/**
|
||||
* Sa-Token-SSO Server端 Controller
|
||||
@ -96,7 +105,7 @@ public class SsoServerController {
|
||||
```
|
||||
注意:在`setDoLoginHandle`函数里如果要获取name, pwd以外的参数,可通过`SaHolder.getRequest().getParam("xxx")`来获取
|
||||
|
||||
##### 1.4、application.yml配置
|
||||
##### 2.3、application.yml配置
|
||||
``` yml
|
||||
# 端口
|
||||
server:
|
||||
@ -123,9 +132,9 @@ spring:
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password:
|
||||
```
|
||||
注意点:`allow-url`为了方便测试配置为*,线上生产环境一定要配置为详细URL地址 (详见下方“配置域名校验”)
|
||||
注意点:`allow-url`为了方便测试配置为`*`,线上生产环境一定要配置为详细URL地址 (详见下方“配置域名校验”)
|
||||
|
||||
##### 1.4、创建SSO-Server端启动类
|
||||
##### 2.4、创建SSO-Server端启动类
|
||||
``` java
|
||||
@SpringBootApplication
|
||||
public class SaSsoServerApplication {
|
||||
@ -137,11 +146,11 @@ public class SaSsoServerApplication {
|
||||
```
|
||||
|
||||
|
||||
### 2、搭建SSO-Client应用端
|
||||
### 3、搭建SSO-Client应用端
|
||||
|
||||
> 搭建示例在官方仓库的 `/sa-token-demo/sa-token-demo-sso2-client/`,如遇到难点可结合源码进行测试学习
|
||||
|
||||
##### 2.1、创建SSO-Client端项目
|
||||
##### 3.1、创建SSO-Client端项目
|
||||
创建一个SpringBoot项目 `sa-token-demo-sso-client`,添加pom依赖:
|
||||
``` xml
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||
@ -171,7 +180,7 @@ public class SaSsoServerApplication {
|
||||
```
|
||||
|
||||
|
||||
##### 1.2、创建SSO-Client端认证接口
|
||||
##### 3.2、创建SSO-Client端认证接口
|
||||
``` java
|
||||
|
||||
/**
|
||||
@ -199,7 +208,7 @@ public class SsoClientController {
|
||||
}
|
||||
```
|
||||
|
||||
##### 1.3、配置SSO认证中心地址
|
||||
##### 3.3、配置SSO认证中心地址
|
||||
你需要在 `application.yml` 配置如下信息:
|
||||
``` yml
|
||||
# 端口
|
||||
@ -228,7 +237,7 @@ sa-token:
|
||||
```
|
||||
注意点:`sa-token.alone-redis` 的配置需要和SSO-Server端连接同一个Redis(database也要一样)
|
||||
|
||||
##### 1.4、写启动类
|
||||
##### 3.4、写启动类
|
||||
``` java
|
||||
@SpringBootApplication
|
||||
public class SaSsoClientApplication {
|
||||
@ -241,18 +250,8 @@ public class SaSsoClientApplication {
|
||||
启动项目
|
||||
|
||||
|
||||
### 3、测试访问
|
||||
### 4、测试访问
|
||||
|
||||
##### 3.1 修改host文件
|
||||
首先修改hosts文件`(C:\windows\system32\drivers\etc\hosts)`,添加以下IP映射,方便我们进行测试:
|
||||
``` url
|
||||
127.0.0.1 sa-sso-server.com
|
||||
127.0.0.1 sa-sso-client1.com
|
||||
127.0.0.1 sa-sso-client2.com
|
||||
127.0.0.1 sa-sso-client3.com
|
||||
```
|
||||
|
||||
##### 3.2 启动项目并访问
|
||||
(1) 依次启动SSO-Server与SSO-Client端,然后从浏览器访问:[http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/)
|
||||
|
||||

|
||||
@ -292,7 +291,7 @@ public class SaSsoClientApplication {
|
||||

|
||||
|
||||
|
||||
### 4、运行官方仓库
|
||||
### 5、运行官方仓库
|
||||
|
||||
以上示例,虽然完整的复现了单点登录的过程,但是页面还是有些简陋,我们可以运行一下官方仓库的示例,里面有制作好的登录页面
|
||||
|
||||
@ -303,9 +302,9 @@ public class SaSsoClientApplication {
|
||||
默认测试密码:`sa / 123456`,其余流程保持不变
|
||||
|
||||
|
||||
### 5、配置域名校验
|
||||
### 6、配置域名校验
|
||||
|
||||
##### 5.1、Ticket劫持攻击
|
||||
##### 6.1、Ticket劫持攻击
|
||||
在以上的SSO-Server端示例中,配置项 `sa-token.sso.allow-url=*` 意为配置所有允许的Client端授权地址,不在此配置项中的URL将无法单点登录成功
|
||||
|
||||
以上示例为了方便测试被配置为*,但是,<font color="#FF0000" >在生产环境中,此配置项绝对不能配置为 * </font>,否则会有被ticket劫持的风险
|
||||
@ -320,7 +319,7 @@ public class SaSsoClientApplication {
|
||||
|
||||
可以看到,代表着用户身份的ticket码也显现到了URL之中,借此漏洞,攻击者完全可以构建一个URL将小红的ticket码自动提交到攻击者自己的服务器,伪造小红身份登录网站
|
||||
|
||||
##### 5.2、防范方法
|
||||
##### 6.2、防范方法
|
||||
|
||||
造成此漏洞的直接原因就是SSO-Server认证中心没有对 `redirect地址` 进行任何的限制,防范的方法也很简单,就是对`redirect参数`进行校验,如果其不在指定的URL列表中时,拒绝下放ticket
|
||||
|
||||
@ -330,7 +329,7 @@ public class SaSsoClientApplication {
|
||||
|
||||
域名没有通过校验,拒绝授权!
|
||||
|
||||
##### 5.3、配置安全性参考表
|
||||
##### 6.3、配置安全性参考表
|
||||
|
||||
| 配置方式 | 举例 | 安全性 | 建议 |
|
||||
| :-------- | :-------- | :-------- | :-------- |
|
||||
@ -339,13 +338,14 @@ public class SaSsoClientApplication {
|
||||
| 配置到详细地址| `http://sa-sso-client1.com:9001/sso/login` | <font color="#080" >高</font> | <font color="#080" >可以在生产环境下使用</font> |
|
||||
|
||||
|
||||
##### 5.4、疑问:为什么不直接回传Token,而是先回传ticket,再用ticket去查询对应的账号id?
|
||||
##### 6.4、疑问:为什么不直接回传Token,而是先回传ticket,再用ticket去查询对应的账号id?
|
||||
Token作为长时间有效的会话凭证,在任何时候都不应该直接在暴露URL之中(虽然Token直接的暴露本身不会造成安全漏洞,但会为很多漏洞提供可乘之机)
|
||||
|
||||
因此Sa-Token-SSO选择先回传ticket,再由ticket获取账号id,且ticket一次性用完即废,提高安全性
|
||||
|
||||
|
||||
### 6、跨Redis的单点登录
|
||||
|
||||
### 7、跨Redis的单点登录
|
||||
以上流程解决了跨域模式下的单点登录,但是后端仍然采用了共享Redis来同步会话,如果我们的架构设计中Client端与Server端无法共享Redis,又该怎么完成单点登录?
|
||||
|
||||
这就要采用模式三了,且往下看:[Http请求获取会话](/sso/sso-type3)
|
||||
|
Loading…
Reference in New Issue
Block a user