SSO核心機制實戰分析 Token驗證與跨域登錄
在分布式系統和微服務架構盛行的當下,單點登錄(Single Sign-On, SSO) 已成為企業級應用的基礎能力。本文將從實戰角度深入剖析SSO的核心機制,聚焦Token驗證與跨域登錄的關鍵技術細節,結合Java實現示例,助你徹底掌握這一面試高頻考點。
一、SSO核心架構與核心問題
SSO的本質是一處登錄,處處通行,其核心架構通常包含:
1. 用戶客戶端 (瀏覽器/App)
2. 業務應用系統 (Service Provider, SP)
3. 認證中心 (Identity Provider, IdP)
核心挑戰:
? 信任傳遞:SP如何信任IdP的認證結果?
? 狀態同步:用戶登錄狀態如何在多個SP間同步?
? 跨域安全:不同域名下如何安全傳遞認證信息?
二、Token:SSO的核心載體
Token是SSO中身份信息的加密載體,替代傳統的Session ID。
1. Token的核心屬性
// JWT Token典型結構 (Header.Payload.Signature)
String header = Base64.encode("{\"alg\":\"HS256\",\"typ\":\"JWT\"}");
String payload = Base64.encode("{\"sub\":\"user123\",\"exp\":1698765432}");
String signature = HMACSHA256(header + "." + payload, SECRET_KEY);
String token = header + "." + payload + "." + signature;
2. 關鍵驗證邏輯(Java實現)
public boolean validateToken(String jwt, String secret) {
String[] parts = jwt.split("\\.");
if (parts.length != 3) return false;
// 1. 驗證簽名
String signature = HMACSHA256(parts[0] + "." + parts[1], secret);
if (!signature.equals(parts[2])) return false;
// 2. 驗證過期時間
String payload = new String(Base64.getUrlDecoder().decode(parts[1]));
long exp = Long.parseLong(JsonParser.parse(payload).getAsJsonObject().get("exp").getAsString());
return System.currentTimeMillis() / 1000 < exp;
}
3. Token安全增強策略
? 短期有效性:Access Token有效期通常≤2小時
? 動態刷新:使用Refresh Token機制
? 綁定設備指紋:Token與設備特征碼綁定
String deviceHash = sha256(userAgent + ipAddress);
payload.put("dvh", deviceHash); // 存入Token
三、跨域登錄實戰:CAS協議深度解析
Central Authentication Service (CAS) 是經典的SSO協議。
1. 跨域登錄核心流程
認證中心(IdP)應用系統(SP)User
認證中心(IdP)
應用系統(SP)
User訪問受保護資源
302重定向到IdP(攜帶service參數)
請求認證
返回登錄頁
提交憑證
302重定向回SP(攜帶Ticket)
攜帶Ticket訪問
驗證Ticket有效性
返回用戶身份
建立局部會話
2. 跨域Ticket驗證關鍵代碼
// SP端驗證Ticket
public UserInfo validateServiceTicket(String ticket, String serviceUrl) {
String validationUrl = "https://idp.com/cas/validate?ticket="
+ ticket + "&service=" + serviceUrl;
HttpClientResponse response = httpClient.get(validationUrl);
// 解析IdP返回的XML/JSON
if (response.getBody().contains("<cas:authenticationSuccess>")) {
return extractUserInfo(response.getBody());
}
throw new InvalidTicketException("Ticket validation failed");
}
3. 跨域會話同步方案
? 方案1:全局Cookie(主域名相同)
Cookie ssoCookie = new Cookie("sso_token", token);
ssoCookie.setDomain(".company.com"); // 設置父級域名
ssoCookie.setHttpOnly(true);
ssoCookie.setSecure(true);
response.addCookie(ssoCookie);
? 方案2:前端跨域傳遞(主域名不同)
// 認證成功后跳轉
window.location.href = `https://app1.com/callback?token=${token}`;
四、安全防御關鍵措施
1. Token劫持防護
? Bind Token技術:
// 生成與當前會話綁定的Token
String sessionId = request.getSession().getId();
String bindToken = sha256(token + sessionId);
redis.set("bind:"+token, bindToken, 300);
2. 重放攻擊防護
// JWT增加唯一標識和時效
payload.put("jti", UUID.randomUUID().toString()); // JWT ID
payload.put("iat", System.currentTimeMillis() / 1000); // 簽發時間
3. 跨站防護(SameSite & CORS)
// 嚴格設置Cookie屬性
response.setHeader("Set-Cookie",
"sso_token=xxxx; SameSite=Strict; Secure; HttpOnly");
五、集群環境下的關鍵實現
1. Token存儲方案對比
方案 | 優點 | 缺點 | 適用場景 |
客戶端存儲 | 無狀態、擴展性好 | Token長度受限 | 移動端/SPA |
Redis集中存儲 | 可強制失效、信息豐富 | 依賴網絡、單點風險 | 高安全要求系統 |
2. 分布式Token刷新機制
// 使用Redis發布訂閱通知刷新
public void refreshToken(String userId) {
String newToken = generateToken(userId);
redis.publish("token-refresh", userId + ":" + newToken);
// 各SP監聽頻道更新本地Token
}
六、面試要點精粹
1. Token vs Session
? Token天然支持跨域,Session依賴Cookie域名
? Token可攜帶元數據,Session需額外存儲查詢
- 跨域登錄核心矛盾
? 安全限制:瀏覽器同源策略阻止跨域Cookie
? 解決方案:前端重定向/后端代理驗證
- OAuth2.0與SSO關系
? OAuth2解決授權問題,SSO解決認證問題
? OpenID Connect = OAuth2.0 + 身份認證(JWT)
總結
SSO的實現本質是圍繞Token的安全生成、傳遞與驗證展開的系統工程。在跨域場景下,需綜合運用:
? 密碼學技術(JWT簽名/加密)
? 協議設計(CAS/OIDC流程)
? 安全策略(防重放/防劫持)
? 基礎設施(Redis集群/HTTPS)
關鍵技術指標參考:
? JWT推薦算法:RS256(非對稱加密)
? Ticket有效期:≤ 10秒(一次性使用)
? 網絡延時容忍:SP到IdP驗證RT ≤ 300ms
掌握這些核心機制,不僅能從容應對面試挑戰,更能為構建高安全、可擴展的分布式認證體系奠定堅實基礎。