优化校验 ticket 的逻辑

This commit is contained in:
click33 2023-06-08 19:36:38 +08:00
parent 30352742f6
commit 5c01deb780
3 changed files with 90 additions and 57 deletions

View File

@ -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

View File

@ -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);
}
/**

View File

@ -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 <T> 要转换的类型
* @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;
}
/**
* 拼接keyTicket 所属的 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;
}