部署避坑實(shí)錄:負(fù)載均衡SSL卸載下的URL斷言失敗與多證書IdP解決方案)
java-saml生產(chǎn)部署避坑實(shí)錄負(fù)載均衡SSL卸載下的URL斷言失敗與多證書IdP解決方案【免費(fèi)下載鏈接】java-samlJava SAML toolkit項(xiàng)目地址: https://gitcode.com/gh_mirrors/jav/java-samljava-samlJava SAML Toolkit是一個幫助 Java 應(yīng)用快速接入 SAML 2.0 單點(diǎn)登錄SSO/單點(diǎn)登出SLO的開源工具包。開發(fā)環(huán)境一切順利但上線后卻莫名失敗本文基于項(xiàng)目源碼與官方文檔拆解生產(chǎn)環(huán)境兩大經(jīng)典故障負(fù)載均衡 SSL 卸載導(dǎo)致的 Destination URL 斷言失敗以及 IdP 多證書/證書輪轉(zhuǎn)導(dǎo)致的簽名驗(yàn)證失敗并給出可直接落地的解決方案 先搞清楚 java-saml 的目錄結(jié)構(gòu)排障才有抓手在動手修坑之前先花一分鐘認(rèn)識項(xiàng)目的三大模塊排障時能迅速定位邏輯模塊路徑職責(zé)corecore/核心解析與驗(yàn)簽邏輯AuthnRequest、SamlResponse、Logout 消息、Settingstoolkittoolkit/面向 Servlet 的高層 APIAuth 類是入口samplessamples/JSP 示例應(yīng)用含 ACS/SLS/Metadata 各端點(diǎn)頁面生產(chǎn)故障大多發(fā)生在URL 校驗(yàn)與簽名校驗(yàn)兩個環(huán)節(jié)下文逐一拆解。坑位一負(fù)載均衡 SSL 卸載下的 URL 斷言失敗癥狀登錄回調(diào)后提示received at ... instead of ...用戶點(diǎn)擊登錄、在 IdP 完成認(rèn)證后瀏覽器被重定向回 SP 的 ACS 端點(diǎn)日志卻拋出類似報錯The response was received at http://10.0.1.5:8080/acs instead of https://app.example.com/acs這條報錯來自 SamlResponse 的 Destination 校驗(yàn)SAML 響應(yīng)里帶有Destination屬性工具包會把它與當(dāng)前請求 URL嚴(yán)格比對不一致即拒絕。根因后端 Tomcat 只看到了內(nèi)網(wǎng)地址和 http典型的生產(chǎn)拓?fù)涫怯脩?→ Nginx/負(fù)載均衡https:443SSL 在此卸載→ Tomcathttp:8080Tomcat 收到的是負(fù)載均衡轉(zhuǎn)發(fā)的請求request.getRequestURL()返回的是內(nèi)網(wǎng) IP http 協(xié)議而 IdP 簽發(fā)的 Destination 是https://app.example.com/acs比對自然失敗。URL 的拼裝邏輯見 ServletUtils 中的getSelfURLhost與getSelfRoutedURLNoQuery方法——它們直接依賴 Servlet 容器的getScheme()、getServerName()、getServerPort()容器感知不到代理拼出來的 URL 就是錯的。最快解決方案讓 Tomcat 感知代理并還原原始 URL官方文檔給出的思路是配置服務(wù)器使其感知代理、返回原始 URL。對 Apache Tomcat在反向代理后的 Connector 上設(shè)置proxyName、proxyPort、scheme、secure屬性即可例如Connector port8080 proxyNameapp.example.com proxyPort443 schemehttps securetrue /若前面是 Nginx也可以啟用RemoteIpValve通過X-Forwarded-For、X-Forwarded-Proto等請求頭還原客戶端地址與協(xié)議。配置生效后getRequestURL()就能返回https://app.example.com/...Destination 斷言隨之通過。 排障口訣先確認(rèn) ACS 端點(diǎn)實(shí)際打印出的請求 URL再對照配置里的onelogin.saml2.sp.assertion_consumer_service.url兩邊必須一字不差??游欢蘒dP 多證書與密鑰輪轉(zhuǎn)下的簽名驗(yàn)證失敗癥狀簽名校驗(yàn)突然失敗日志提示Signature validation failed企業(yè)級 IdP如 ADFS、Keycloak 等常常出現(xiàn)兩種情況簽名與加密使用不同證書處于密鑰輪轉(zhuǎn)期元數(shù)據(jù)中同時發(fā)布多張證書。此時僅配置單張onelogin.saml2.idp.x509cert會間歇性報Signature validation failed. SAML Response rejected。解決方案x509certMulti 配置追加驗(yàn)簽證書工具包原生支持多證書驗(yàn)簽。以 AuthnResponse 多證書測試用例 為例驗(yàn)證邏輯位于 SamlResponse驗(yàn)簽時會把x509cert與x509certMulti列表合并成候選證書鏈逐一嘗試任意一張驗(yàn)簽成功即通過。配置方法與 SettingsBuilder 中定義的屬性鍵一致onelogin.saml2.idp.x509cert 主證書PEM onelogin.saml2.idp.x509certMulti[0] 第二張證書PEM onelogin.saml2.idp.x509certMulti[1] 第三張證書PEM兩點(diǎn)注意事項(xiàng)加密仍只用主證書只有x509cert會用于斷言解密多證書僅參與驗(yàn)簽SLO 同樣生效LogoutRequest 與 LogoutResponse 的驗(yàn)簽也走同一套多證書列表登出鏈路無需額外處理。若你的 IdP 元數(shù)據(jù)是動態(tài)拉取的IdPMetadataParser 解析元數(shù)據(jù)時會自動提取多張證書并填充到x509certMulti可免去手工維護(hù)。生產(chǎn)環(huán)境安全配置清單務(wù)必逐條核對除了兩個大坑以下配置項(xiàng)直接關(guān)系到生產(chǎn)安全參考官方 README 與 Saml2Settings配置項(xiàng)生產(chǎn)建議說明onelogin.saml2.strict必須true否則拒簽、寬松解析等保護(hù)全部失效onelogin.saml2.idp.x509cert用完整證書棄用指紋指紋是哈希值存在碰撞繞過簽名驗(yàn)證的風(fēng)險onelogin.saml2.security.want_assertions_signed按需true強(qiáng)制斷言簽名消息 ID 去重記錄getLastMessageId()防御重放攻擊緩存 TTL 覆蓋斷言有效期即可關(guān)于重放攻擊處理完 SAML 響應(yīng)后用 Auth 的getLastMessageId()取出消息 ID 存入 Redis/DB相同 ID 二次出現(xiàn)直接拒絕即可無需長期保存。常見問題速查表故障現(xiàn)象大概率原因解決動作received at http://內(nèi)網(wǎng)IP... instead of https://域名...負(fù)載均衡 SSL 卸載后端 URL 失真配置 TomcatproxyName/proxyPort/scheme/secure或 RemoteIpValve簽名驗(yàn)證失敗且 IdP 正在換證書僅配置了單張 IdP 證書增加onelogin.saml2.idp.x509certMulti[N]登錄偶發(fā)成功、偶發(fā)失敗時鐘漂移觸發(fā)斷言時效校驗(yàn)全鏈路啟用 NTP 校時登出鏈路驗(yàn)簽失敗漏配 SLO 相關(guān)多證書復(fù)用同一份 x509certMulti無需單獨(dú)處理總結(jié)三句話記住生產(chǎn)部署要點(diǎn)URL 一致性讓 Servlet 容器感知代理使getRequestURL()還原出用戶可見的 https 域名 URLDestination 斷言才能通過驗(yàn)簽證書鏈用x509certMulti覆蓋簽名/加密分離與密鑰輪轉(zhuǎn)場景主證書保留給加密收緊開關(guān)stricttrue 完整證書驗(yàn)簽 消息 ID 去重是 java-saml 生產(chǎn)環(huán)境不可妥協(xié)的底線。配合 samples 模塊中的 JSP 示例如 acs.jsp在測試環(huán)境復(fù)現(xiàn)同樣配置絕大多數(shù)生產(chǎn) SSO 故障都能被提前攔截 【免費(fèi)下載鏈接】java-samlJava SAML toolkit項(xiàng)目地址: https://gitcode.com/gh_mirrors/jav/java-saml創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考