簡體   English   中英

Flask_oidc 在 Docker 容器中運行時給出“Errno 99 無法分配請求的地址”

[英]Flask_oidc gives `Errno 99 Cannot assign requested address` when run in Docker container

目標:

在 Docker 容器中運行的 Flask 應用程序中使用 OIDC。

背景:

我正在使用 Flask 構建一個 Web 應用程序,並希望使用 Keycloak 來提供訪問權限。 為此,我使用 Python 庫 flask_oidc。

所有服務都使用 docker-compose 文件在本地運行:

  • 運行 Flask 應用程序的 Gunicorn(端口 5000)
  • 鑰匙斗篷(端口 8080)

我遵循了https://gist.github.com/thomasdarimont/145dc9aa857b831ff2eff221b79d179a的示例,甚至將我的應用程序簡化為這個。

問題:

  1. 啟動所有服務
  2. 導航到需要登錄的服務(示例中為/private
  3. 用戶被重新路由到提示登錄的 Keycloud 服務器。
  4. 用戶登錄。
  5. Keycloak 將用戶路由應用程序 ( /oidc_callback )
  6. !!! Flask 應用程序崩潰並出現OSError: [Errno 99] Cannot assign requested address錯誤。

這是在嘗試連接到 Keycloak 服務器時在flask_oidc > oauth2client > httplib2中引起的。

認為正在發生的是庫嘗試打開與 Keycloak 服務器的連接,但嘗試將其綁定到localhost 這可能會失敗,因為在 Docker 容器內,應用程序綁定到0.0.0.0

我嘗試了什么:

[ WORKS ] 在容器外運行 Gunicorn/Flask 應用程序,並在容器內運行 Keylcoak。

這表明(對我而言)我的所有設置和代碼都很好,但問題出在 Docker<-->flask_oidc+ 之間的交互中。

問題:誰能解釋一下? 我真的希望有人有一個工作設置(在 docker 中使用 flask_oidc 的 Flask),並且願意分享這個。

更新 [2018 年 5 月 12 日]我想我明白了。 我使用 PyOIDC 手動完成所有步驟並能夠進行調試。

在您自己的計算機( localhost )上在 Docker 中運行這兩個服務時,您會遇到沖突:

  • 用戶去localhost:8080查找 Keycloak 和localhost:5000查找 App。
  • Flask 應用程序在容器內運行,並且localhost不會解析到主機,而是解析到容器內的自身。
  • 可以讓 Flask 使用容器中的網絡連接到http://keycloak/隨后它會返回該域下的所有配置。 這很糟糕,因為對於外界來說它應該是localhost:8080

現在,如果您實際上有域名(例如 keycloak.awesome.app 和 app.awesome.app),我認為它會正常工作,因為它會使用外部 DNS 將其解析為 IP 地址,即正確的機器。

獎勵: PyOIDC 可以從 Keycloak 中檢索提供程序配置,因此無需為此手動輸入。 耶!

新設置對於本地開發,我決定進行如下設置:

(1) 添加到/etc/hosts : 127.0.0.1 keycloak.dev.local 127.0.0.1 app.dev.local

(2) 在docker-compose.yml中添加到您的 Flask 服務: extra_hosts: #host.docker.internal is not accepted. - "keycloak.dev.local:<YOUR IP ADRESS>" - "app.dev.local:<YOUR IP ADRESS>" extra_hosts: #host.docker.internal is not accepted. - "keycloak.dev.local:<YOUR IP ADRESS>" - "app.dev.local:<YOUR IP ADRESS>"

(=) 現在,您和 Flask 應用程序都可以訪問keycloak.dev.local並且可以正確響應!

請注意,我仍然希望有一個更好的解決方案。 一旦我的 IP 地址更改,此設置就會失敗。

flask-oidc 從客戶端機密文件中獲取令牌端點配置。

我設法通過進行以下更改使其工作:

  1. 燒瓶應用keycloak容器創建了一個 docker 網絡;
  2. 編輯了屬性userinfo_uritoken_uritoken_introspection_uri ,將主機名替換為 keycloak 容器主機名(我使用的是 docker-compose,在這種情況下,keycloak 容器主機名是服務名稱)。

例子:

{
  "web": {
    "auth_uri": "http://localhost:8080/auth/realms/REMOVED/protocol/openid-connect/auth",
    "client_id": "flask-client",
    "client_secret": "REMOVED",
    "redirect_uris": ["http://localhost:5000/oidc_callback"],
    "userinfo_uri": "http://keycloak:8080/auth/realms/REMOVED/protocol/openid-connect/userinfo",
    "token_uri": "http://keycloak:8080/auth/realms/REMOVED/protocol/openid-connect/token",
    "token_introspection_uri": "http://keycloak:8080/auth/realms/REMOVED/protocol/openid-connect/token/introspect"
  }
}

現在它通過 docker 網絡連接以交換令牌信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM