mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-12-19 19:46:56 +08:00
sso 模块新增 maxRegClient 属性,用于控制模式三下 client 注册数量
This commit is contained in:
@@ -13,9 +13,9 @@ public class SaSso2ClientApplication {
|
||||
System.out.println();
|
||||
System.out.println("---------------------- Sa-Token SSO 模式二 Client 端启动成功 ----------------------");
|
||||
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
|
||||
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9001");
|
||||
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9001");
|
||||
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9001");
|
||||
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9002");
|
||||
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9002");
|
||||
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9002");
|
||||
System.out.println("测试前需要根据官网文档修改hosts文件,测试账号密码:sa / 123456");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 9001
|
||||
port: 9002
|
||||
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
sa-token:
|
||||
# 每次登录时,产生不同的token
|
||||
is-share: false
|
||||
# SSO-相关配置
|
||||
sso-client:
|
||||
# SSO-Server端 统一认证地址
|
||||
|
||||
@@ -13,9 +13,9 @@ public class SaSso3ClientApplication {
|
||||
System.out.println();
|
||||
System.out.println("---------------------- Sa-Token SSO 模式三 Client 端启动成功 ----------------------");
|
||||
System.out.println("配置信息:" + SaSsoManager.getClientConfig());
|
||||
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9001");
|
||||
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9001");
|
||||
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9001");
|
||||
System.out.println("测试访问应用端一: http://sa-sso-client1.com:9003");
|
||||
System.out.println("测试访问应用端二: http://sa-sso-client2.com:9003");
|
||||
System.out.println("测试访问应用端三: http://sa-sso-client3.com:9003");
|
||||
System.out.println("测试前需要根据官网文档修改hosts文件,测试账号密码:sa / 123456");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 9001
|
||||
port: 9003
|
||||
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package cn.dev33.satoken.sso.model;
|
||||
|
||||
|
||||
import cn.dev33.satoken.sso.util.SaSsoConsts;
|
||||
|
||||
/**
|
||||
* Sa-Token SSO Model
|
||||
*
|
||||
@@ -24,6 +26,11 @@ package cn.dev33.satoken.sso.model;
|
||||
*/
|
||||
public class SaSsoClientModel {
|
||||
|
||||
/*
|
||||
* 只能记录模式三登录的 client 信息,模式一和模式二的信息即使记录上,也无法完成单点注销操作,遂不记录
|
||||
* 所以:mode、tokenValue 字段,仅留作扩展,暂时无用
|
||||
*/
|
||||
|
||||
/**
|
||||
* 此 client 登录模式(1=模式一,2=模式二,3=模式三)
|
||||
*/
|
||||
@@ -34,15 +41,15 @@ public class SaSsoClientModel {
|
||||
*/
|
||||
public String client;
|
||||
|
||||
/**
|
||||
* 此次登录 token 值
|
||||
*/
|
||||
public String tokenValue;
|
||||
// /**
|
||||
// * 此次登录 token 值
|
||||
// */
|
||||
// public String tokenValue;
|
||||
|
||||
/**
|
||||
* 单点注销回调url
|
||||
*/
|
||||
public String ssoLogoutCall;
|
||||
public String sloCallbackUrl;
|
||||
|
||||
/**
|
||||
* 此 client 注册信息的时间,13位时间戳
|
||||
@@ -57,10 +64,15 @@ public class SaSsoClientModel {
|
||||
public SaSsoClientModel() {
|
||||
}
|
||||
|
||||
public SaSsoClientModel(String client, String ssoLogoutCall) {
|
||||
/**
|
||||
* 模式三构建
|
||||
*/
|
||||
public SaSsoClientModel(String client, String sloCallbackUrl, int index) {
|
||||
this.mode = SaSsoConsts.SSO_MODE_3;
|
||||
this.client = client;
|
||||
this.ssoLogoutCall = ssoLogoutCall;
|
||||
this.sloCallbackUrl = sloCallbackUrl;
|
||||
this.regTime = System.currentTimeMillis();
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,43 +116,43 @@ public class SaSsoClientModel {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 此次登录 token 值
|
||||
*
|
||||
* @return tokenValue 此次登录 token 值
|
||||
*/
|
||||
public String getTokenValue() {
|
||||
return this.tokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 此次登录 token 值
|
||||
*
|
||||
* @param tokenValue 此次登录 token 值
|
||||
* @return /
|
||||
*/
|
||||
public SaSsoClientModel setTokenValue(String tokenValue) {
|
||||
this.tokenValue = tokenValue;
|
||||
return this;
|
||||
}
|
||||
// /**
|
||||
// * 获取 此次登录 token 值
|
||||
// *
|
||||
// * @return tokenValue 此次登录 token 值
|
||||
// */
|
||||
// public String getTokenValue() {
|
||||
// return this.tokenValue;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 设置 此次登录 token 值
|
||||
// *
|
||||
// * @param tokenValue 此次登录 token 值
|
||||
// * @return /
|
||||
// */
|
||||
// public SaSsoClientModel setTokenValue(String tokenValue) {
|
||||
// this.tokenValue = tokenValue;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取 单点注销回调url
|
||||
*
|
||||
* @return ssoLogoutCall 单点注销回调url
|
||||
*/
|
||||
public String getSsoLogoutCall() {
|
||||
return this.ssoLogoutCall;
|
||||
public String getSloCallbackUrl() {
|
||||
return this.sloCallbackUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 单点注销回调url
|
||||
*
|
||||
* @param ssoLogoutCall 单点注销回调url
|
||||
* @param sloCallbackUrl 单点注销回调url
|
||||
* @return /
|
||||
*/
|
||||
public SaSsoClientModel setSsoLogoutCall(String ssoLogoutCall) {
|
||||
this.ssoLogoutCall = ssoLogoutCall;
|
||||
public SaSsoClientModel setSloCallbackUrl(String sloCallbackUrl) {
|
||||
this.sloCallbackUrl = sloCallbackUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -189,8 +201,8 @@ public class SaSsoClientModel {
|
||||
return "SaSsoClientModel{" +
|
||||
"mode=" + mode +
|
||||
", client='" + client + '\'' +
|
||||
", tokenValue='" + tokenValue + '\'' +
|
||||
", ssoLogoutCall='" + ssoLogoutCall + '\'' +
|
||||
// ", tokenValue='" + tokenValue + '\'' +
|
||||
", sloCallbackUrl='" + sloCallbackUrl + '\'' +
|
||||
", regTime=" + regTime +
|
||||
", index=" + index +
|
||||
'}';
|
||||
|
||||
@@ -227,10 +227,13 @@ public class SaSsoClientProcessor {
|
||||
|
||||
// 获取参数
|
||||
String loginId = req.getParamNotNull(paramName.loginId);
|
||||
// String client = req.getParam(paramName.client);
|
||||
// String autoLogout = req.getParam(paramName.autoLogout);
|
||||
|
||||
// 校验参数签名
|
||||
if(ssoConfig.getIsCheckSign()) {
|
||||
ssoClientTemplate.getSignTemplate(ssoConfig.getClient()).checkRequest(req, paramName.loginId);
|
||||
ssoClientTemplate.getSignTemplate(ssoConfig.getClient()).
|
||||
checkRequest(req, paramName.loginId, paramName.client, paramName.autoLogout);
|
||||
} else {
|
||||
SaSsoManager.printNoCheckSignWarningByRuntime();
|
||||
}
|
||||
@@ -289,7 +292,11 @@ public class SaSsoClientProcessor {
|
||||
}
|
||||
} else {
|
||||
// q2、使用模式二:直连Redis校验ticket
|
||||
// return ssoClientTemplate.checkTicket(ticket);
|
||||
// 注意此处调用了 SaSsoServerProcessor 处理器里的方法,
|
||||
// 这意味着如果你的 sso-server 端重写了 SaSsoServerProcessor 里的部分方法,
|
||||
// 而在当前 sso-client 没有按照相应格式重写 SaSsoClientProcessor 里的方法,
|
||||
// 可能会导致调用失败(注意是可能,而非一定),
|
||||
// 解决方案为:在当前 sso-client 端也按照 sso-server 端的格式重写 SaSsoClientProcessor 里的方法
|
||||
return SaSsoServerProcessor.instance.ssoServerTemplate.checkTicket(ticket, cfg.getClient());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
|
||||
return SaSsoManager.getClientConfig();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------- SSO 模式三相关 -------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,12 +17,12 @@ package cn.dev33.satoken.sso.template;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.sso.util.SaSsoConsts;
|
||||
import cn.dev33.satoken.sso.SaSsoManager;
|
||||
import cn.dev33.satoken.sso.config.SaSsoServerConfig;
|
||||
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
|
||||
import cn.dev33.satoken.sso.exception.SaSsoException;
|
||||
import cn.dev33.satoken.sso.model.SaSsoClientModel;
|
||||
import cn.dev33.satoken.sso.util.SaSsoConsts;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
@@ -266,44 +266,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------- SSO 模式三相关 -------------------
|
||||
|
||||
/**
|
||||
* 为指定账号id注册单点注销回调URL
|
||||
* @param loginId 账号id
|
||||
* @param client 指定客户端标识,可为null
|
||||
* @param sloCallbackUrl 单点注销时的回调URL
|
||||
*/
|
||||
public void registerSloCallbackUrl(Object loginId, String client, String sloCallbackUrl) {
|
||||
// 如果提供的参数是空值,则直接返回,不进行任何操作
|
||||
if(SaFoxUtil.isEmpty(loginId) || SaFoxUtil.isEmpty(sloCallbackUrl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaSession session = getStpLogic().getSessionByLoginId(loginId);
|
||||
|
||||
// 取出原来的
|
||||
List<SaSsoClientModel> scmList = session.get(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, ArrayList::new);
|
||||
|
||||
// 将 新登录client 加入到集合中
|
||||
SaSsoClientModel scm = new SaSsoClientModel();
|
||||
scm.mode = 3;
|
||||
scm.client = client;
|
||||
scm.ssoLogoutCall = sloCallbackUrl;
|
||||
scm.regTime = System.currentTimeMillis();
|
||||
scm.index = calcNextIndex(scmList);
|
||||
scmList.add(scm);
|
||||
|
||||
// 如果登录的client数量超过了限制,则将最早的一个登录进行清退
|
||||
if(scmList.size() > getServerConfig().getMaxRegClient()) {
|
||||
SaSsoClientModel removeScm = scmList.remove(0);
|
||||
notifyClientLogout(loginId, removeScm, true);
|
||||
}
|
||||
|
||||
// 存入持久库
|
||||
session.set(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, scmList);
|
||||
}
|
||||
// ------------------- SSO -------------------
|
||||
|
||||
/**
|
||||
* 指定账号单点注销
|
||||
@@ -327,60 +290,12 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
|
||||
getStpLogic().logout(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知指定账号的指定客户端注销
|
||||
* @param loginId 指定账号
|
||||
* @param scm 客户端信息对象
|
||||
* @param autoLogout 是否为超过 maxRegClient 的自动注销
|
||||
*/
|
||||
public void notifyClientLogout(Object loginId, SaSsoClientModel scm, boolean autoLogout) {
|
||||
|
||||
// 如果给个null值,不进行任何操作
|
||||
if(scm == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是模式二登录的
|
||||
if(scm.mode == SaSsoConsts.SSO_MODE_2) {
|
||||
// 获取登录 token
|
||||
String tokenValue = scm.tokenValue;
|
||||
if(SaFoxUtil.isEmpty(tokenValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 注销此 token
|
||||
getStpLogic().logoutByTokenValue(scm.tokenValue);
|
||||
}
|
||||
|
||||
// 如果是模式三登录的
|
||||
else if(scm.mode != SaSsoConsts.SSO_MODE_3) {
|
||||
// url
|
||||
String sloCallUrl = scm.getSsoLogoutCall();
|
||||
if(SaFoxUtil.isEmpty(sloCallUrl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 参数
|
||||
Map<String, Object> paramsMap = new TreeMap<>();
|
||||
paramsMap.put(paramName.client, scm.getClient());
|
||||
paramsMap.put(paramName.loginId, loginId);
|
||||
paramsMap.put(paramName.autoLogout, autoLogout);
|
||||
String signParamsStr = getSignTemplate(scm.getClient()).addSignParamsAndJoin(paramsMap);
|
||||
|
||||
// 拼接
|
||||
String finalUrl = SaFoxUtil.joinParam(sloCallUrl, signParamsStr);
|
||||
|
||||
// 发起请求
|
||||
getServerConfig().sendHttp.apply(finalUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算下一个 index 值
|
||||
* @param scmList /
|
||||
* @return /
|
||||
*/
|
||||
private int calcNextIndex(List<SaSsoClientModel> scmList) {
|
||||
public int calcNextIndex(List<SaSsoClientModel> scmList) {
|
||||
// 如果目前还没有任何登录记录,则直接返回0
|
||||
if(scmList == null || scmList.isEmpty()) {
|
||||
return 0;
|
||||
@@ -394,7 +309,79 @@ public class SaSsoServerTemplate extends SaSsoTemplate {
|
||||
}
|
||||
|
||||
// 否则返回最大值+1
|
||||
return maxIndex++;
|
||||
maxIndex++;
|
||||
return maxIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定账号id注册单点注销回调信息(模式三)
|
||||
* @param loginId 账号id
|
||||
* @param client 指定客户端标识,可为null
|
||||
* @param sloCallbackUrl 单点注销时的回调URL
|
||||
*/
|
||||
public void registerSloCallbackUrl(Object loginId, String client, String sloCallbackUrl) {
|
||||
// 如果提供的参数是空值,则直接返回,不进行任何操作
|
||||
if(SaFoxUtil.isEmpty(loginId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaSession session = getStpLogic().getSessionByLoginId(loginId);
|
||||
|
||||
// 取出原来的
|
||||
List<SaSsoClientModel> scmList = session.get(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, ArrayList::new);
|
||||
|
||||
// 将 新登录client 加入到集合中
|
||||
SaSsoClientModel scm = new SaSsoClientModel(client, sloCallbackUrl, calcNextIndex(scmList));
|
||||
scmList.add(scm);
|
||||
|
||||
// 如果登录的client数量超过了限制,则从最早的一个登录开始清退
|
||||
int maxRegClient = getServerConfig().maxRegClient;
|
||||
if(maxRegClient != -1) {
|
||||
for (;;) {
|
||||
if(scmList.size() > maxRegClient) {
|
||||
SaSsoClientModel removeScm = scmList.remove(0);
|
||||
notifyClientLogout(loginId, removeScm, true);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 存入持久库
|
||||
session.set(SaSsoConsts.SSO_CLIENT_MODEL_LIST_KEY_, scmList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知指定账号的指定客户端注销
|
||||
* @param loginId 指定账号
|
||||
* @param scm 客户端信息对象
|
||||
* @param autoLogout 是否为超过 maxRegClient 的自动注销
|
||||
*/
|
||||
public void notifyClientLogout(Object loginId, SaSsoClientModel scm, boolean autoLogout) {
|
||||
|
||||
// 如果给个null值,不进行任何操作
|
||||
if(scm == null || scm.mode != SaSsoConsts.SSO_MODE_3) {
|
||||
return;
|
||||
}
|
||||
|
||||
// url
|
||||
String sloCallUrl = scm.getSloCallbackUrl();
|
||||
if(SaFoxUtil.isEmpty(sloCallUrl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 参数
|
||||
Map<String, Object> paramsMap = new TreeMap<>();
|
||||
paramsMap.put(paramName.client, scm.getClient());
|
||||
paramsMap.put(paramName.loginId, loginId);
|
||||
paramsMap.put(paramName.autoLogout, autoLogout);
|
||||
String signParamsStr = getSignTemplate(scm.getClient()).addSignParamsAndJoin(paramsMap);
|
||||
|
||||
// 拼接
|
||||
String finalUrl = SaFoxUtil.joinParam(sloCallUrl, signParamsStr);
|
||||
|
||||
// 发起请求
|
||||
getServerConfig().sendHttp.apply(finalUrl);
|
||||
}
|
||||
|
||||
// ---------------------- 构建URL ----------------------
|
||||
|
||||
@@ -21,9 +21,6 @@ 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.util.SaResult;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sa-Token SSO 模板方法类 (公共端)
|
||||
@@ -81,5 +78,4 @@ public class SaSsoTemplate {
|
||||
return SaManager.getSaSignTemplate();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class SaSsoUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定账号单点注销
|
||||
* 指定账号单点注销 (以Server方发起)
|
||||
* @param loginId 指定账号
|
||||
*/
|
||||
public static void ssoLogout(Object loginId) {
|
||||
|
||||
Reference in New Issue
Block a user