動態

詳情 返回 返回

keycloak~關於跨域的iframe對接keycloak的分析 - 動態 詳情

幾個cookie下面元素

  • AUTH_SESSION_ID 會話級的session_state
  • AUTH_SESSION_ID_LEGACY 在http中可見的AUTH_SESSION_ID
  • KEYCLOAK_SESSION 帶有效期的session_state
  • KEYCLOAK_SESSION_LEGACY 在http中可見的KEYCLOAK_SESSION
  • KEYCLOAK_IDENTITY 用户完成認證後,在cookie記錄用户和session_state的jwt token
  • KEYCLOAK_IDENTITY_LEGACY 在http中可見的KEYCLOAK_IDENTITY

不同頂級域名對接keycloak後auth_session_id被cookie Partition隔離

圖片

登錄的過程

以社區登錄為例,對接社區如微信登錄後,在keycloak登錄頁點微信按鈕,

  1. 登錄頁面 /auth/realms/demo/protocol/openid-connect/auth
  2. 驗證參數,完成到社區網站的302跳轉 /auth/realms/{realm}/broker/weixin/login?client_id=democlient&tab_id=rzukcX7mOfQ&session_code=OPsAHAZ3HZISaxklQLmcVYJThVUwLh5Y8TkAi5GQPjY
  3. 在社區網站上完成登錄,由社區302跳轉回keycloak頁面
  4. 如果社區帳號沒有綁定keycloak用户,進入first-broker-login頁面,完成用户的綁定 /auth/realms/demo/login-actions/first-broker-login?client_id=democlient&tab_id=JCCx2WFmFFA
  5. 在first-broker-login填寫信息提交後,完成綁定,302到post-broker-login頁面 /auth/realms/demo/login-actions/post-broker-login?client_id=democlient&tab_id=dBh9Jl7qib4
  6. post-broker-login流程處理完成後,302到after-post-broker-login頁面,/auth/realms/demo/broker/after-post-broker-login?session_code=QM5PnTZihZqnVsyCilwJhxLY5viLoCgckPLHF_NkBuA&client_id=democlient&tab_id=dBh9Jl7qib4
  7. 這樣就完成了keycloak的登錄,然後302跳轉到redirect_uri頁面,登錄結束

跨域iframe登錄出現問題的點

  1. 打開登錄頁後,生成auth_session_id這個鍵,並添加了當前域名的頂級域名做為cookie的Partition Key
  2. 點擊社區登錄後,kc服務端進入如下方法
  • org.keycloak.services.resources.IdentityBrokerService.performLogin()
    • org.keycloak.services.resources.IdentityBrokerService.parseSessionCode()
      • org.keycloak.services.resources.SessionCodeChecks.initialVerify()
  1. 經過sessionCode初始檢查之後,在執行到parseSessionCode()方法中代碼AuthenticationSessionModel authSession = checks.getAuthenticationSession();時,authSession的結果為空,故出現無法登錄異常,如下代碼
ERROR [org.keycloak.services.resources.IdentityBrokerService] (default task-1708) unexpectedErrorHandlingRequestMessage: javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
	at org.keycloak.keycloak-services@14.0.0//org.keycloak.services.resources.IdentityBrokerService.parseSessionCode(IdentityBrokerService.java:1225)
	at org.keycloak.keycloak-services@14.0.0//org.keycloak.services.resources.IdentityBrokerService.performLogin(IdentityBrokerService.java:419)

跨域後的異常

  1. 有同域的auth_session_id的情況下(已在cookie partitioned為空的網站登錄,與kc認證服務同一頂級域名),在跨域頁面登錄,請求是http 302跳到新登錄頁,顯示登錄超時(或者強制跳到已登錄頁面),原因是kc服務端獲取的auth_session_id與當前頁面傳遞的tab_id和session_code不匹配
    圖片

  2. 在沒有其它auth_session_id的情況下,在跨域頁面登錄,顯示錯誤頁,http 400錯誤,原因是kc服務端在無法獲取cookie中帶分區的auth_session_id
    圖片

  3. keycloak使用了會話保持功能,我們使用更穩定的ingress在瀏覽器添加cookie的方式,當在社區超鏈登錄時,它的a標籤裏target屬性為_parent或者_top,這樣鏈接發送的cookie是cookie partitioned為空的網站route(狀態保持自動生成),這時會出現請求的kc節點與提交的kc節點不同的情況,也會出現400的錯誤

解決iframe跨域問題的關鍵

  1. 表單提交登錄,可以適應跨頂域的情況
  2. 社區a標籤超鏈登錄,如果target=_self,也可以適應跨頂域的情況,其它target屬性,不適合
  3. 建議統一登錄不使用iframe進行嵌入

Add a new 評論

Some HTML is okay.