2021-08-24 02:05:16 +08:00
|
|
|
|
# Sa-Token-SSO整合-常见问题总结
|
|
|
|
|
|
2022-10-26 13:20:27 +08:00
|
|
|
|
SSO 集成常见问题整理
|
|
|
|
|
|
|
|
|
|
[[toc]]
|
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 问:在模式一与模式二中,Client端 必须通过 Alone-Redis 插件来访问Redis吗?
|
|
|
|
|
答:不必须,只是推荐,权限缓存与业务缓存分离后会减少 `SSO-Redis` 的访问压力,且可以避免多个 `Client端` 的缓存读写冲突
|
|
|
|
|
|
2022-04-29 03:23:46 +08:00
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
### 问:将旧有系统改造为单点登录时,应该注意哪些?
|
|
|
|
|
答:建议不要把其中一个系统改造为SSO服务端,而是新起一个项目作为Server端,所有旧有项目全部作为Client端与此对接
|
|
|
|
|
|
2022-04-29 03:23:46 +08:00
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
### 问:SSO模式二,第一个域名登录成功之后其他两个不会自动登录?
|
|
|
|
|
答:系统1登录成功之后,系统二与系统三需要点击登录按钮,才会登录成功
|
|
|
|
|
|
|
|
|
|
> 第一个系统,需要:点击 [登录] 按钮 -> 跳转到登录页 -> 输账号密码 -> 登录成功 <br>
|
|
|
|
|
> 第二个系统,需要:点击 [登录] 按钮 -> 登录成功 <br>
|
|
|
|
|
> 第三个系统,需要:点击 [登录] 按钮 -> 登录成功 (免去重复跳转登录页输入账号密码的步骤)
|
|
|
|
|
|
2022-04-29 03:23:46 +08:00
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
### 追问:那我是否可以设计成不需要点登录按钮的,只要访问页面,它就能登录成功
|
|
|
|
|
可以:加个过滤器检测到未登录 自动跳转就行了,详细可以参照章节:[[何时引导用户去登录]](/sso/sso-custom-login) 给出的建议进行设计
|
|
|
|
|
|
2022-04-29 03:23:46 +08:00
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
### 问:我参照文档的SSO模式二搭建,一直提示:Ticket无效,请问怎么回事?
|
|
|
|
|
根据群友的反馈,出现此异常概率最大的原因是因为 `Client` 与 `Server` 没有连接同一个Redis,SSO模式二中两者必须连接同一个 Redis 才可以登录成功,
|
|
|
|
|
如果您排查之后不是此原因,可以加入QQ群或者在issues反馈一下
|
|
|
|
|
|
2022-04-29 03:23:46 +08:00
|
|
|
|
|
|
|
|
|
### 模式一或者模式二报错:Could not write JSON: No serializer found for class com.pj.sso.SysUser and no properties discovered to create BeanSerializer
|
|
|
|
|
|
|
|
|
|
一般是因为在 sso-server 端往 session 上写入了某个实体类(比如 User),而在 sso-client 端没有这个实体类,导致反序列化失败。
|
|
|
|
|
|
|
|
|
|
解决方案:在 sso-client 也新建上这个类,而且包名需要与 sso-server 端的一致(直接从 sso-server 把实体类复制过来就好了)
|
|
|
|
|
|
|
|
|
|
|
2022-05-06 10:31:46 +08:00
|
|
|
|
### 问:如果 sso-client 端我没有集成 sa-token-sso,如何对接?
|
|
|
|
|
需要手动调用 http 请求来对接 sso-server 开放的接口,参考示例:[sa-token-demo-sso3-client-nosdk](https://gitee.com/dromara/sa-token/tree/master/sa-token-demo/sa-token-demo-sso3-client-nosdk)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 问:如果 sso-client 端不是 java语言,可以对接吗?
|
|
|
|
|
可以,只不过有点麻烦,基本思路和上个问题一致,需要手动调用 http 请求来对接 sso-server 开放的接口,参考:
|
|
|
|
|
[SSO-Server 认证中心开放接口](/sso/sso-apidoc)
|
|
|
|
|
|
|
|
|
|
|
2022-10-26 13:20:27 +08:00
|
|
|
|
### 问:怎么在一个项目里同时搭建 sso-server 和 sso-client?
|
|
|
|
|
|
|
|
|
|
难点在于解决两边的路由冲突,示例代码:
|
|
|
|
|
|
|
|
|
|
``` java
|
|
|
|
|
// Sa-Token SSO Controller
|
|
|
|
|
@RestController
|
|
|
|
|
public class SsoController {
|
|
|
|
|
|
|
|
|
|
// 处理 SSO-Server 端所有请求
|
|
|
|
|
@RequestMapping({"/sso/auth", "/sso/doLogin", "/sso/checkTicket", "/sso/signout"})
|
|
|
|
|
public Object ssoServerRequest() {
|
|
|
|
|
return SaSsoProcessor.instance.serverDister();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理 SSO-Client 端所有请求
|
|
|
|
|
@RequestMapping({"/sso/login", "/sso/logout", "/sso/logoutCall"})
|
|
|
|
|
public Object ssoClientRequest() {
|
|
|
|
|
return SaSsoProcessor.instance.clientDister();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置SSO相关参数
|
|
|
|
|
@Autowired
|
|
|
|
|
private void configSso(SaSsoConfig sso) {
|
|
|
|
|
// SSO配置代码,参考文档前几章 ...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 问:我一个项目里有两套账号体系,都需要单点登录,怎么在一个项目里同时搭建两个 sso-server 服务?
|
|
|
|
|
|
|
|
|
|
首先推荐你不要在一个项目里同时搭建两个 sso-server,建议创建两个项目,分别搭建各自的 sso-server 服务。
|
|
|
|
|
|
|
|
|
|
如果一定要在一个项目中搭建两套 sso-server 服务,参考方案如下:
|
|
|
|
|
|
|
|
|
|
第一套,还是用前面几章文档给出的示例代码。
|
|
|
|
|
|
|
|
|
|
第二套,修改一些参数属性,使之与第一套不产生冲突,参考代码如下:
|
|
|
|
|
|
|
|
|
|
``` java
|
|
|
|
|
/**
|
|
|
|
|
* Sa-Token-SSO 第二套 SSO-Server端 Controller
|
|
|
|
|
*/
|
|
|
|
|
@RestController
|
|
|
|
|
public class SsoUserServerController {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 新建一个 SaSsoProcessor 请求处理器
|
|
|
|
|
*/
|
|
|
|
|
public static SaSsoProcessor ssoUserProcessor = new SaSsoProcessor();
|
|
|
|
|
static {
|
|
|
|
|
// 自定义一个 SaSsoTemplate 对象
|
|
|
|
|
SaSsoTemplate ssoUserTemplate = new SaSsoTemplate() {
|
|
|
|
|
// 使用的会话对象 是自定义的 StpUserUtil
|
|
|
|
|
@Override
|
|
|
|
|
public StpLogic getStpLogic() {
|
|
|
|
|
return StpUserUtil.stpLogic;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// 让这个SSO请求处理器,使用的路由前缀是 /sso-user,而不是原先的 /sso
|
|
|
|
|
ssoUserTemplate.apiName.replacePrefix("/sso-user");
|
|
|
|
|
|
|
|
|
|
// 给这个 SSO 请求处理器使用自定义的 SaSsoTemplate 对象
|
|
|
|
|
ssoUserProcessor.ssoTemplate = ssoUserTemplate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 第二套 sso-server 服务:处理所有SSO相关请求
|
|
|
|
|
* http://{host}:{port}/sso-user/auth -- 单点登录授权地址,接受参数:redirect=授权重定向地址
|
|
|
|
|
* http://{host}:{port}/sso-user/doLogin -- 账号密码登录接口,接受参数:name、pwd
|
|
|
|
|
* http://{host}:{port}/sso-user/checkTicket -- Ticket校验接口(isHttp=true时打开),接受参数:ticket=ticket码、ssoLogoutCall=单点注销回调地址 [可选]
|
|
|
|
|
* http://{host}:{port}/sso-user/signout -- 单点注销地址(isSlo=true时打开),接受参数:loginId=账号id、secretkey=接口调用秘钥
|
|
|
|
|
*/
|
|
|
|
|
@RequestMapping("/sso-user/*")
|
|
|
|
|
public Object ssoUserRequest() {
|
|
|
|
|
return ssoUserProcessor.serverDister();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 自定义 doLogin 方法 */
|
|
|
|
|
// 注意点:
|
|
|
|
|
// 1、第2套 sso-server 对应的 RestApi 登录接口也应该更换为 /sso-user/doLogin,而不是原先的 /sso/doLogin
|
|
|
|
|
// 2、在这里,登录函数要使用自定义的 StpUserUtil.login(),而不是原先的 StpUtil.login()
|
|
|
|
|
@RequestMapping("/sso-user/doLogin")
|
|
|
|
|
public Object ssoUserRequest(String name, String pwd) {
|
|
|
|
|
if("sa".equals(name) && "123456".equals(pwd)) {
|
|
|
|
|
StpUserUtil.login(10001);
|
|
|
|
|
return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
|
|
|
|
|
}
|
|
|
|
|
return SaResult.error("登录失败!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-10-18 00:18:58 +08:00
|
|
|
|
<br/>
|
2022-05-06 10:31:46 +08:00
|
|
|
|
|
2022-10-26 13:20:27 +08:00
|
|
|
|
---
|
|
|
|
|
|
2022-10-18 00:18:58 +08:00
|
|
|
|
<details>
|
|
|
|
|
<summary>还有其它问题?</summary>
|
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
可以加群反馈一下,比较典型的问题我们解决之后都会提交到此页面方便大家快速排查
|
2022-10-18 00:18:58 +08:00
|
|
|
|
</details>
|
|
|
|
|
|
2021-08-24 02:05:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|