使用 OpenID Connect 保護應用程式和服務

使用 Keycloak 的 OpenID Connect 來保護應用程式和服務

可用的端點

作為一個完全符合 OpenID Connect 提供者實作的 Keycloak,它公開了一組端點,應用程式和服務可以使用這些端點來驗證和授權其使用者。

本節描述您的應用程式和服務與 Keycloak 互動時應使用的一些主要端點。

端點

最需要了解的端點是 well-known 組態端點。它列出了與 Keycloak 中 OpenID Connect 實作相關的端點和其他組態選項。該端點為

/realms/{realm-name}/.well-known/openid-configuration

要取得完整 URL,請加入 Keycloak 的基本 URL,並將 {realm-name} 取代為您的領域名稱。例如

https://127.0.0.1:8080/realms/master/.well-known/openid-configuration

某些 RP 程式庫會從這個端點擷取所有需要的端點,但對於其他程式庫,您可能需要個別列出端點。

授權端點

/realms/{realm-name}/protocol/openid-connect/auth

授權端點執行最終使用者的驗證。此驗證是透過將使用者代理重新導向到此端點來完成的。

如需更多詳細資訊,請參閱 OpenID Connect 規範中的 授權端點 章節。

Token 端點

/realms/{realm-name}/protocol/openid-connect/token

Token 端點用於取得 Token。Token 可以透過交換授權碼取得,也可以根據使用的流程直接提供憑證取得。Token 端點也用於在存取 Token 過期時取得新的存取 Token。

如需更多詳細資訊,請參閱 OpenID Connect 規範中的 Token 端點 章節。

Userinfo 端點

/realms/{realm-name}/protocol/openid-connect/userinfo

Userinfo 端點會傳回有關已驗證使用者的標準聲明;此端點受到持有者 Token 的保護。

如需更多詳細資訊,請參閱 OpenID Connect 規範中的 Userinfo 端點 章節。

登出端點

/realms/{realm-name}/protocol/openid-connect/logout

登出端點會登出已驗證的使用者。

使用者代理可以重新導向到該端點,這會導致活動的使用者工作階段登出。然後,使用者代理會重新導向回應用程式。

應用程式也可以直接調用該端點。若要直接調用此端點,需要包含重新整理 Token 以及驗證用戶端所需的憑證。

憑證端點

/realms/{realm-name}/protocol/openid-connect/certs

憑證端點會傳回領域啟用的公開金鑰,並編碼為 JSON Web Key (JWK)。根據領域設定,可以啟用一個或多個金鑰來驗證 Token。如需更多資訊,請參閱 伺服器管理指南JSON Web Key 規範

內省端點

/realms/{realm-name}/protocol/openid-connect/token/introspect

內省端點用於擷取 Token 的活動狀態。換句話說,您可以使用它來驗證存取 Token 或重新整理 Token。此端點只能由機密用戶端調用。

如需有關如何調用此端點的更多詳細資訊,請參閱 OAuth 2.0 Token 內省規範

使用 application/jwt 標頭觸發的內省端點

您可以使用 HTTP 標頭 Accept: application/jwt 而非 Accept: application/json 來調用內省端點。如果為 application/jwt,則回應可能包含額外的聲明 jwt,其中包含完整的 JWT 存取 Token,如果您要內省的 Token 是輕量型存取 Token,則這會特別有用。這需要您在用戶端進階設定中啟用 Support JWT claim in Introspection Response,這會觸發 Token 內省。

動態用戶端註冊端點

/realms/{realm-name}/clients-registrations/openid-connect

動態用戶端註冊端點用於動態註冊用戶端。

如需更多詳細資訊,請參閱 用戶端註冊服務 指南和 OpenID Connect 動態用戶端註冊規範

Token 撤銷端點

/realms/{realm-name}/protocol/openid-connect/revoke

Token 撤銷端點用於撤銷 Token。此端點支援重新整理 Token 和存取 Token。當撤銷重新整理 Token 時,也會撤銷相應用戶端的使用者同意。

如需有關如何調用此端點的更多詳細資訊,請參閱 OAuth 2.0 Token 撤銷規範

裝置授權端點

/realms/{realm-name}/protocol/openid-connect/auth/device

裝置授權端點用於取得裝置程式碼和使用者程式碼。機密或公開用戶端皆可調用此端點。

如需有關如何調用此端點的更多詳細資訊,請參閱 OAuth 2.0 裝置授權授與規範

後端通道驗證端點

/realms/{realm-name}/protocol/openid-connect/ext/ciba/auth

後端通道驗證端點用於取得 auth_req_id,以識別用戶端提出的驗證請求。此端點只能由機密用戶端調用。

如需有關如何調用此端點的更多詳細資訊,請參閱 OpenID Connect 用戶端起始的後端通道驗證流程規範

支援的授與類型

本節說明提供給轉送方的不同授與類型。

授權碼

授權碼流程會將使用者代理重新導向到 Keycloak。一旦使用者在 Keycloak 中成功驗證,就會建立一個授權碼,並且使用者代理會重新導向回應用程式。然後,應用程式會使用授權碼及其憑證,從 Keycloak 取得存取 Token、重新整理 Token 和 ID Token。

此流程的目標是 Web 應用程式,但也建議用於原生應用程式,包括行動應用程式,在這些應用程式中可以嵌入使用者代理。

如需更多詳細資訊,請參閱 OpenID Connect 規範中的 授權碼流程

隱式

隱式流程的工作方式與授權碼流程類似,但會傳回存取 Token 和 ID Token,而不是傳回授權碼。這種方法減少了交換授權碼以取得存取 Token 的額外調用需求。但是,它不包含重新整理 Token。這導致需要允許具有長到期時間的存取 Token;然而,這種方法並不實際,因為很難使這些 Token 失效。或者,您可以在初始存取 Token 過期後,要求重新導向以取得新的存取 Token。如果應用程式只想驗證使用者並自行處理登出,則隱式流程很有用。

您可以改用混合流程,其中會傳回存取 Token 和授權碼。

需要注意的一件事是,隱式流程和混合流程都存在潛在的安全風險,因為存取 Token 可能會透過 Web 伺服器記錄和瀏覽器歷史記錄洩漏。您可以使用較短的存取 Token 到期時間來稍微減輕此問題。

如需更多詳細資訊,請參閱 OpenID Connect 規範中的 隱式流程

根據目前的 OAuth 2.0 安全最佳實務,不應使用此流程。此流程已從未來的 OAuth 2.1 規範 中移除。

資源擁有者密碼憑證

資源擁有者密碼憑證 (在 Keycloak 中稱為直接授與) 允許交換使用者憑證以取得 Token。根據目前的 OAuth 2.0 安全最佳實務,不應使用此流程,最好採用替代方法,例如 裝置授權授與授權碼

使用此流程的限制包括

  • 使用者憑證會暴露給應用程式

  • 應用程式需要登入頁面

  • 應用程式需要知道驗證方案

  • 驗證流程的變更需要變更應用程式

  • 不支援身分中介或社群登入

  • 不支援流程 (使用者自行註冊、必要動作等等)。

此流程的安全疑慮包括

  • 讓 Keycloak 以外的更多部分參與憑證的處理

  • 增加可能發生憑證洩漏的脆弱表面區域

  • 建立一個生態系統,讓使用者信任另一個應用程式輸入其憑證而不是 Keycloak

若要允許用戶端使用資源擁有者密碼憑證授與,用戶端必須啟用 Direct Access Grants Enabled 選項。

此流程未包含在 OpenID Connect 中,但它是 OAuth 2.0 規範的一部分。它已從未來的 OAuth 2.1 規範 中移除。

如需更多詳細資訊,請參閱 OAuth 2.0 規範中的 資源擁有者密碼憑證授與 章節。

使用 CURL 的範例

以下範例顯示如何使用使用者名稱 user 和密碼 password,為領域 master 中的使用者取得存取 Token。此範例使用的是機密用戶端 myclient

curl \
  -d "client_id=myclient" \
  -d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
  -d "username=user" \
  -d "password=password" \
  -d "grant_type=password" \
  "https://127.0.0.1:8080/realms/master/protocol/openid-connect/token"

用戶端憑證

當用戶端 (應用程式和服務) 想要代表自己取得存取權,而不是代表使用者時,會使用用戶端憑證。例如,這些憑證對於在系統上進行變更的背景服務,而不是針對特定使用者來說,會很有用。

Keycloak 支援用戶端使用機密或公開/私密金鑰進行驗證。

此流程未包含在 OpenID Connect 中,但它是 OAuth 2.0 規範的一部分。

如需更多詳細資訊,請參閱 OAuth 2.0 規範中的 用戶端憑證授與 章節。

裝置授權授與

裝置授權授與適用於在輸入功能有限或缺少合適瀏覽器的網路連線裝置上執行的用戶端。

  1. 應用程式會請求 Keycloak 提供裝置程式碼和使用者程式碼。

  2. Keycloak 會建立裝置程式碼和使用者程式碼。

  3. Keycloak 會傳回包含裝置程式碼和使用者程式碼的回應給應用程式。

  4. 應用程式會向使用者提供使用者程式碼和驗證 URI。使用者會存取驗證 URI,以使用另一個瀏覽器進行驗證。

  5. 應用程式會重複輪詢 Keycloak,直到 Keycloak 完成使用者授權。

  6. 如果使用者驗證完成,則應用程式會取得裝置程式碼。

  7. 應用程式會使用裝置代碼及其憑證,從 Keycloak 取得存取權杖 (Access Token)、重新整理權杖 (Refresh Token) 和 ID 權杖 (ID Token)。

如需更多詳細資訊,請參閱 OAuth 2.0 裝置授權許可規範

用戶端啟動的回溯通道驗證許可

用戶端啟動的回溯通道驗證許可 (Client Initiated Backchannel Authentication Grant) 是由想要直接與 OpenID 提供者通訊,以啟動驗證流程的用戶端使用,而無需像 OAuth 2.0 的授權碼許可那樣透過使用者瀏覽器重新導向。

用戶端會向 Keycloak 請求一個 auth_req_id,以識別用戶端發出的驗證請求。Keycloak 會建立 auth_req_id。

收到此 auth_req_id 後,用戶端需要重複輪詢 Keycloak,以取得 Keycloak 回應的存取權杖、重新整理權杖和 ID 權杖,直到使用者通過驗證。

如果用戶端使用 ping 模式,則不需要重複輪詢權杖端點,而是可以等待 Keycloak 發送到指定用戶端通知端點的通知。用戶端通知端點可以在 Keycloak 管理主控台中設定。用戶端通知端點合約的詳細資訊在 CIBA 規範中說明。

如需更多詳細資訊,請參閱 OpenID Connect 用戶端啟動的回溯通道驗證流程規範

另請參閱 Keycloak 文件中的其他地方,例如本指南的 回溯通道驗證端點和伺服器管理指南的 用戶端啟動的回溯通道驗證許可章節。有關 FAPI CIBA 合規性的詳細資訊,請參閱本指南的 FAPI 章節

Keycloak 特定的錯誤

Keycloak 伺服器可以在 OIDC 驗證回應中,向用戶端應用程式發送錯誤,並帶有參數 error=temporarily_unavailableerror_description=authentication_expired。當使用者已通過驗證並擁有 SSO 會話時,但目前的瀏覽器分頁中的驗證會話已過期,因此 Keycloak 伺服器無法自動執行使用者的 SSO 重新驗證並使用成功的回應重新導向回用戶端時,Keycloak 會發送此錯誤。當用戶端應用程式收到此類型的錯誤時,最好立即重試驗證,並向 Keycloak 伺服器發送新的 OIDC 驗證請求,這通常應始終驗證使用者,因為 SSO 會話並重新導向回用戶端。如需更多詳細資訊,請參閱 伺服器管理指南

金融級 API (FAPI) 支援

Keycloak 使管理員更容易確保其用戶端符合這些規範

此合規性表示 Keycloak 伺服器將驗證規範中提及的授權伺服器的要求。Keycloak 配接器沒有對 FAPI 的任何特定支援,因此可能仍需要在用戶端(應用程式)端手動或透過其他第三方解決方案進行必要的驗證。

FAPI 用戶端設定檔

為確保您的用戶端符合 FAPI,您可以在您的領域中設定用戶端原則,如 伺服器管理指南所述,並將其連結到每個領域中自動提供的 FAPI 支援的全域用戶端設定檔。您可以根據您的用戶端需要符合的 FAPI 設定檔,使用 fapi-1-baselinefapi-1-advanced 設定檔。您也可以使用 fapi-2-security-profilefapi-2-message-signing 設定檔,以符合 FAPI 2 草案規範。

如果您想使用 推送授權請求 (PAR),建議您的用戶端同時使用 fapi-1-baseline 設定檔和 fapi-1-advanced 設定檔進行 PAR 請求。具體來說,fapi-1-baseline 設定檔包含 pkce-enforcer 執行器,可確保用戶端使用具有安全 S256 演算法的 PKCE。除非他們使用 PAR 請求,否則這對於 FAPI Advanced 用戶端不是必需的。

如果您想以符合 FAPI 的方式使用 CIBA,請確保您的用戶端同時使用 fapi-1-advancedfapi-ciba 用戶端設定檔。需要使用 fapi-1-advanced 設定檔或包含請求執行器的其他用戶端設定檔,因為 fapi-ciba 設定檔僅包含 CIBA 特定的執行器。在強制執行 FAPI CIBA 規範的要求時,需要更多要求,例如強制執行機密用戶端或憑證綁定的存取權杖。

巴西開放金融金融級 API 安全設定檔

Keycloak 符合 巴西開放金融金融級 API 安全設定檔 1.0 實施者草案 3。此規範在某些要求上比 FAPI 1 Advanced 規範更嚴格,因此可能需要以更嚴格的方式設定 用戶端原則,以強制執行某些要求。特別是

  • 如果您的用戶端不使用 PAR,請確保它使用加密的 OIDC 請求物件。這可以透過使用具有 secure-request-object 執行器的用戶端設定檔來實現,並啟用 Encryption Required

  • 確保對於 JWS,用戶端使用 PS256 演算法。對於 JWE,用戶端應使用帶有 A256GCMRSA-OAEP。這可能需要在所有適用這些演算法的 用戶端設定中設定。

澳大利亞消費者資料權 (CDR) 安全設定檔

如果您想應用澳大利亞 CDR 安全設定檔,您需要使用 fapi-1-advanced 設定檔,因為澳大利亞 CDR 安全設定檔基於 FAPI 1.0 Advanced 安全設定檔。如果您的用戶端也應用 PAR,請確保用戶端應用 RFC 7637 程式碼交換證明金鑰 (PKCE),因為澳大利亞 CDR 安全設定檔要求您在應用 PAR 時應用 PKCE。這可以透過使用帶有 pkce-enforcer 執行器的用戶端設定檔來實現。

TLS 考量

由於正在交換機密資訊,因此所有互動都應使用 TLS (HTTPS) 加密。此外,FAPI 規範中對使用的密碼套件和 TLS 協定版本有一些要求。若要符合這些要求,您可以考慮設定允許的密碼。可以透過設定 https-protocolshttps-cipher-suites 選項來完成此設定。Keycloak 預設使用 TLSv1.3,因此可能不需要變更預設設定。但是,如果您由於某些原因需要回退到較低的 TLS 版本,則可能需要調整密碼。如需更多詳細資訊,請參閱 設定 TLS 指南。

OAuth 2.1 支援

Keycloak 使管理員更容易確保其用戶端符合這些規範

此合規性表示 Keycloak 伺服器將驗證規範中提及的授權伺服器的要求。Keycloak 配接器沒有對 OAuth 2.1 的任何特定支援,因此可能仍需要在用戶端(應用程式)端手動或透過其他第三方解決方案進行必要的驗證。

OAuth 2.1 用戶端設定檔

為確保您的用戶端符合 OAuth 2.1,您可以在您的領域中設定用戶端原則,如 伺服器管理指南中所述,並將其連結到每個領域中自動提供的 OAuth 2.1 支援的全域用戶端設定檔。您可以針對機密用戶端使用 oauth-2-1-for-confidential-client 設定檔,或針對公用用戶端使用 oauth-2-1-for-public-client 設定檔。

OAuth 2.1 規範仍然是草案,將來可能會變更。因此,Keycloak 內建的 OAuth 2.1 用戶端設定檔也可能會變更。
當使用公用用戶端的 OAuth 2.1 設定檔時,建議使用 DPoP 預覽功能,如 伺服器管理指南中所述,因為 DPoP 將存取權杖和重新整理權杖與用戶端金鑰組的公用部分繫結在一起。此繫結可防止攻擊者使用被盜的權杖。

建議

本節說明使用 Keycloak 保護您的應用程式時的一些建議。

驗證存取權杖

如果您需要手動驗證 Keycloak 發出的存取權杖,您可以呼叫 自省端點。這種方法的缺點是您必須對 Keycloak 伺服器進行網路呼叫。如果同時進行的驗證請求太多,這可能會很慢並可能使伺服器超載。Keycloak 發出的存取權杖是使用 JSON Web Token (JWT) 數位簽署和使用 JSON Web Signature (JWS) 編碼的。因為它們以這種方式編碼,所以您可以使用發行領域的公鑰在本地驗證存取權杖。您可以在驗證程式碼中硬式編碼領域的公鑰,或使用內嵌在 JWS 中的金鑰 ID (KID),使用 憑證端點查詢和快取公鑰。根據您使用的程式語言,存在許多第三方程式庫,它們可以協助您進行 JWS 驗證。

重新導向 URI

當使用基於重新導向的流程時,請務必為您的用戶端使用有效的重新導向 uri。重新導向 uri 應盡可能具體。這尤其適用於用戶端(公用用戶端)應用程式。如果未能執行此操作,可能會導致

  • 開放式重新導向 - 這可以允許攻擊者建立看起來像是來自您網域的詐騙連結

  • 未經授權的存取 - 當使用者已經通過 Keycloak 驗證時,攻擊者可以使用未正確設定重新導向 uri 的公用用戶端,在使用者不知情的情況下重新導向使用者以取得存取權

在 Web 應用程式的生產環境中,始終對所有重新導向 URI 使用 https。不要允許重新導向到 http。

還存在一些特殊的重新導向 URI

http://127.0.0.1

此重新導向 URI 對於原生應用程式很有用,並允許原生應用程式在隨機埠上建立 Web 伺服器,該埠可用於取得授權碼。此重新導向 URI 允許任何埠。請注意,根據 適用於原生應用程式的 OAuth 2.0建議使用 localhost,而應改為使用 IP 字面值 127.0.0.1

urn:ietf:wg:oauth:2.0:oob

如果您無法在客戶端啟動網頁伺服器(或無法使用瀏覽器),您可以使用特殊的 urn:ietf:wg:oauth:2.0:oob 重新導向 URI。當使用此重新導向 URI 時,Keycloak 會顯示一個頁面,頁面標題和頁面上的方塊中都會顯示授權碼。應用程式可以偵測瀏覽器標題是否已變更,或者使用者可以手動複製並貼上授權碼到應用程式中。透過此重新導向 URI,使用者可以使用不同的裝置取得授權碼,再將授權碼貼回應用程式。

在此頁面上