From 5c01deb780d0568042401f944c10b55d8338c9c8 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Thu, 8 Jun 2023 19:36:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=A1=E9=AA=8C=20ticket?= =?UTF-8?q?=20=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 2 +- .../cn/dev33/satoken/sso/SaSsoProcessor.java | 11 +- .../cn/dev33/satoken/sso/SaSsoTemplate.java | 134 +++++++++++------- 3 files changed, 90 insertions(+), 57 deletions(-) diff --git a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/resources/application.yml index 9f5aad02..af6f09fe 100644 --- a/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/src/main/resources/application.yml @@ -5,7 +5,7 @@ server: # sa-token配置 sa-token: # SSO-相关配置 - sso: + sso: # SSO-Server端 统一认证地址 auth-url: http://sa-sso-server.com:9000/sso/auth # auth-url: http://127.0.0.1:8848/sa-token-demo-sso-server-h5/sso-auth.html diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java index d07df254..873785a4 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoProcessor.java @@ -141,16 +141,15 @@ public class SaSsoProcessor { // 校验ticket,获取 loginId Object loginId = ssoTemplate.checkTicket(ticket, client); + if(SaFoxUtil.isEmpty(loginId)) { + return SaResult.error("无效ticket:" + ticket); + } // 注册此客户端的单点注销回调URL ssoTemplate.registerSloCallbackUrl(loginId, sloCallback); - // 给 client 端响应结果 - if(SaFoxUtil.isEmpty(loginId)) { - return SaResult.error("无效ticket:" + ticket); - } else { - return SaResult.data(loginId); - } + // 给 client 端响应结果 + return SaResult.data(loginId); } /** diff --git a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java index e9afff6c..f173f25d 100644 --- a/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java +++ b/sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/SaSsoTemplate.java @@ -95,42 +95,20 @@ public class SaSsoTemplate { // ---------------------- Ticket 操作 ---------------------- - + /** - * 根据 账号id 创建一个 Ticket码 - * @param loginId 账号id - * @param client 客户端标识 - * @return Ticket码 - */ - public String createTicket(Object loginId, String client) { - // 创建 Ticket - String ticket = randomTicket(loginId); - - // 保存 Ticket - saveTicket(ticket, loginId, client); - saveTicketIndex(ticket, loginId); - - // 返回 Ticket - return ticket; - } - - /** - * 保存 Ticket + * 保存 Ticket 关联的 loginId * @param ticket ticket码 - * @param loginId 账号id - * @param client 客户端标识 + * @param loginId 账号id */ - public void saveTicket(String ticket, Object loginId, String client) { - String value = String.valueOf(loginId); - if(SaFoxUtil.isNotEmpty(client)) { - value += "," + client; - } + public void saveTicket(String ticket, Object loginId) { + // 保存 ticket -> loginId 的关系 long ticketTimeout = SaSsoManager.getConfig().getTicketTimeout(); - SaManager.getSaTokenDao().set(splicingTicketSaveKey(ticket), value, ticketTimeout); + SaManager.getSaTokenDao().set(splicingTicketSaveKey(ticket), String.valueOf(loginId), ticketTimeout); } /** - * 保存 Ticket 索引 + * 保存 Ticket 索引 (id 反查 ticket) * @param ticket ticket码 * @param loginId 账号id */ @@ -138,7 +116,20 @@ public class SaSsoTemplate { long ticketTimeout = SaSsoManager.getConfig().getTicketTimeout(); SaManager.getSaTokenDao().set(splicingTicketIndexKey(loginId), String.valueOf(ticket), ticketTimeout); } - + + /** + * 保存 Ticket 关联的 client + * @param ticket ticket码 + * @param client 客户端标识 + */ + public void saveTicketToClient(String ticket, String client) { + if(SaFoxUtil.isEmpty(client)) { + return; + } + long ticketTimeout = SaSsoManager.getConfig().getTicketTimeout(); + SaManager.getSaTokenDao().set(splicingTicketToClientSaveKey(ticket), client, ticketTimeout); + } + /** * 删除 Ticket * @param ticket Ticket码 @@ -162,7 +153,18 @@ public class SaSsoTemplate { } /** - * 根据 Ticket码 获取账号id,如果Ticket码无效则返回null + * 删除 Ticket 关联的 client + * @param ticket Ticket码 + */ + public void deleteTicketToClient(String ticket) { + if(ticket == null) { + return; + } + SaManager.getSaTokenDao().delete(splicingTicketToClientSaveKey(ticket)); + } + + /** + * 查询 ticket 指向的 loginId,如果 ticket 码无效则返回 null * @param ticket Ticket码 * @return 账号id */ @@ -170,17 +172,11 @@ public class SaSsoTemplate { if(SaFoxUtil.isEmpty(ticket)) { return null; } - String loginId = SaManager.getSaTokenDao().get(splicingTicketSaveKey(ticket)); - // 如果是 "a,b" 的格式,则只取最前面的一项 - if(loginId != null && loginId.contains(",")) { - String[] arr = loginId.split(","); - loginId = arr[0]; - } - return loginId; + return SaManager.getSaTokenDao().get(splicingTicketSaveKey(ticket)); } /** - * 根据 Ticket码 获取账号id,并转换为指定类型 + * 查询 ticket 指向的 loginId,并转换为指定类型 * @param 要转换的类型 * @param ticket Ticket码 * @param cs 要转换的类型 @@ -191,7 +187,7 @@ public class SaSsoTemplate { } /** - * 查询 指定账号id的 Ticket值 + * 查询 指定 loginId 其所属的 ticket 值 * @param loginId 账号id * @return Ticket值 */ @@ -202,6 +198,39 @@ public class SaSsoTemplate { return SaManager.getSaTokenDao().get(splicingTicketIndexKey(loginId)); } + /** + * 查询 ticket 关联的 client,如果 ticket 码无效则返回 null + * @param ticket Ticket码 + * @return 账号id + */ + public String getTicketToClient(String ticket) { + if(SaFoxUtil.isEmpty(ticket)) { + return null; + } + return SaManager.getSaTokenDao().get(splicingTicketToClientSaveKey(ticket)); + } + + // + + /** + * 根据 账号id 创建一个 Ticket码 + * @param loginId 账号id + * @param client 客户端标识 + * @return Ticket码 + */ + public String createTicket(Object loginId, String client) { + // 创建 Ticket + String ticket = randomTicket(loginId); + + // 保存 Ticket + saveTicket(ticket, loginId); + saveTicketIndex(ticket, loginId); + saveTicketToClient(ticket, client); + + // 返回 Ticket + return ticket; + } + /** * 校验 Ticket 码,获取账号id,如果此ticket是有效的,则立即删除 * @param ticket Ticket码 @@ -223,23 +252,19 @@ public class SaSsoTemplate { if(loginId != null) { - // 如果是 "a,b" 的格式,则解析出对应的 Client - String ticketClient = null; - if(loginId.contains(",")) { - String[] arr = loginId.split(","); - loginId = arr[0]; - ticketClient = arr[1]; - } + // 解析出这个 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); } - + // 删除 ticket 信息,使其只有一次性有效 deleteTicket(ticket); deleteTicketIndex(loginId); + deleteTicketToClient(ticket); } // @@ -559,7 +584,16 @@ public class SaSsoTemplate { * @return key */ public String splicingTicketSaveKey(String ticket) { - return SaManager.getConfig().getTokenName() + ":ticket:" + ticket; + return getStpLogic().getConfigOrGlobal().getTokenName() + ":ticket:" + ticket; + } + + /** + * 拼接key:Ticket 查 所属的 client + * @param ticket ticket值 + * @return key + */ + public String splicingTicketToClientSaveKey(String ticket) { + return getStpLogic().getConfigOrGlobal().getTokenName() + ":ticket-client:" + ticket; } /** @@ -568,7 +602,7 @@ public class SaSsoTemplate { * @return key */ public String splicingTicketIndexKey(Object id) { - return SaManager.getConfig().getTokenName() + ":id-ticket:" + id; + return getStpLogic().getConfigOrGlobal().getTokenName() + ":id-ticket:" + id; }