diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java index 9f748ade..c27bfdff 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/error/SaSsoErrorCode.java @@ -59,4 +59,7 @@ public interface SaSsoErrorCode { /** 当前缺少配置 server-url 地址 */ int CODE_30012 = 30012; + /** 提供的 client 参数值无效 */ + int CODE_30013 = 30013; + } diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java index 22fea638..c99e5f5e 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/processor/SaSsoServerProcessor.java @@ -20,6 +20,8 @@ import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.context.model.SaResponse; 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.name.ApiName; import cn.dev33.satoken.sso.name.ParamName; import cn.dev33.satoken.sso.template.SaSsoServerTemplate; @@ -112,8 +114,16 @@ public class SaSsoServerProcessor { return res.redirect(redirect); } else { // 方式2:带着ticket参数重定向回Client端 (mode=ticket) + + // 校验提供的client是否为非法字符 + String client = req.getParam(paramName.client); + if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) { + throw new SaSsoException("无效 client 标识:" + client).setCode(SaSsoErrorCode.CODE_30013); + } + + // 开始重定向 String redirectUrl = ssoServerTemplate.buildRedirectUrl( - stpLogic.getLoginId(), req.getParam(paramName.client), req.getParam(paramName.redirect)); + stpLogic.getLoginId(), client, req.getParam(paramName.redirect)); return res.redirect(redirectUrl); } } @@ -145,7 +155,12 @@ public class SaSsoServerProcessor { String ticket = req.getParamNotNull(paramName.ticket); String sloCallback = req.getParam(paramName.ssoLogoutCall); - // 2、校验签名 + // 2、校验提供的client是否为非法字符 + if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) { + return SaResult.error("无效 client 标识:" + client); + } + + // 3、校验签名 if(ssoServerTemplate.getServerConfig().getIsCheckSign()) { ssoServerTemplate.getSignTemplate(client).checkRequest(req, paramName.client, paramName.ticket, paramName.ssoLogoutCall); @@ -153,16 +168,16 @@ public class SaSsoServerProcessor { SaSsoManager.printNoCheckSignWarningByRuntime(); } - // 3、校验ticket,获取 loginId + // 4、校验ticket,获取 loginId Object loginId = ssoServerTemplate.checkTicket(ticket, client); if(SaFoxUtil.isEmpty(loginId)) { return SaResult.error("无效ticket:" + ticket); } - // 4、注册此客户端的单点注销回调URL + // 5、注册此客户端的单点注销回调URL ssoServerTemplate.registerSloCallbackUrl(loginId, client, sloCallback); - // 5、给 client 端响应结果 + // 6、给 client 端响应结果 return SaResult.data(loginId); } diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java index 1c60027b..42255ac0 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java @@ -187,7 +187,7 @@ public class SaSsoServerTemplate extends SaSsoTemplate { * @return 账号id */ public Object checkTicket(String ticket) { - return checkTicket(ticket, null); + return checkTicket(ticket, SaSsoConsts.CLIENT_WILDCARD); } /** @@ -205,10 +205,17 @@ public class SaSsoServerTemplate extends SaSsoTemplate { // 解析出这个 ticket 关联的 Client String ticketClient = getTicketToClient(ticket); - // 如果指定了 client 标识,则校验一下 client 标识是否一致 - if(SaFoxUtil.isNotEmpty(client) && SaFoxUtil.notEquals(client, ticketClient)) { - throw new SaSsoException("该 ticket 不属于 client=" + client + ", ticket 值: " + ticket) - .setCode(SaSsoErrorCode.CODE_30011); + // 校验 client 参数是否正确,即:创建 ticket 的 client 和当前校验 ticket 的 client 是否一致 + if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) { + // 如果提供的是通配符,直接越过 client 校验 + } else if (SaFoxUtil.isEmpty(client) && SaFoxUtil.isEmpty(ticketClient)) { + // 如果提供的和期望的两者均为空,则通过校验 + } else { + // 开始详细比对 + if(SaFoxUtil.notEquals(client, ticketClient)) { + throw new SaSsoException("该 ticket 不属于 client=" + client + ", ticket 值: " + ticket) + .setCode(SaSsoErrorCode.CODE_30011); + } } // 删除 ticket 信息,使其只有一次性有效 diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java index 64050ae7..8eea64f4 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/util/SaSsoConsts.java @@ -45,6 +45,9 @@ public class SaSsoConsts { /** 表示请求没有得到任何有效处理 {msg: "not handle"} */ public static final String NOT_HANDLE = "{\"msg\": \"not handle\"}"; + /** client 身份,* 代表通配,可以解析出所有 client 的 ticket */ + public static final String CLIENT_WILDCARD = "*"; + /** SSO 模式1 */ public static final int SSO_MODE_1 = 1; /** SSO 模式2 */ @@ -52,4 +55,6 @@ public class SaSsoConsts { /** SSO 模式3 */ public static final int SSO_MODE_3 = 3; + + }