在Docker容器中运行时,Flask_oidc给出“ Errno 99无法分配请求的地址”

时间:2018-12-04 13:16:51

标签: python docker flask oidc

目标:

在Docker容器中运行的Flask应用中使用OIDC。

背景

我正在用Flask构建一个Web应用程序,并想使用Keycloak提供访问权限。为此,我使用了Python库flask_oidc。

所有服务均使用docker-compose文件在本地运行:

  • 运行Flask应用程序(端口5000)的独角兽
  • 密钥斗篷(端口8080)

我遵循了https://gist.github.com/thomasdarimont/145dc9aa857b831ff2eff221b79d179a的示例,甚至将我的应用程序简化为这样。

问题:

  1. 启动所有服务
  2. 导航到需要登录的服务(在示例中为/private
  3. 用户被重新路由到Keycloud服务器,提示登录。
  4. 用户登录。
  5. Keycloak将用户 back 路由到应用(/oidc_callback
  6. !!! Flask应用程序崩溃,出现OSError: [Errno 99] Cannot assign requested address错误。

这是在尝试连接到Keycloak服务器时在flask_oidc> oauth2client> httplib2中引起的。

认为正在发生的事情是该库尝试打开与Keycloak服务器的连接,但是尝试将其绑定到localhost。这可能会失败,因为在Docker容器中,应用程序已绑定到0.0.0.0

我尝试过的事情:

[工作]在容器外部运行Gunicorn / Flask应用程序,然后在容器内部运行Keylcoak。

(向我显示)我的所有设置和代码都很好,但问题出在Docker <-> flask_oidc +之间的交互中。

问题: 谁能解释一下?我真的希望有人可以进行安装(使用flask_oidc在docker内部安装Flask),并愿意分享。

更新[5-12-2018] 我想我知道了。我使用PyOIDC手动完成所有步骤并能够调试。

在自己的计算机(localhost)上在Docker中运行这两种服务时,您会遇到冲突:

  • 用户转到localhost:8080查找Keycloak,然后转到localhost:5000查找应用程序。
  • Flask应用程序在容器内运行,并且localhost不能解析为 host ,而是解析为容器内的自身。
  • 可以使用容器中的网络让Flask连接到http://keycloak/,但但是然后它将返回此域下的所有配置。这很不好,因为对外界来说应该是localhost:8080

现在,如果您实际上拥有域名(例如keycloak.awesome.app和app.awesome.app),我认为它会很好用,因为它将使用外部DNS将其解析为IP地址,这是正确的机器。

奖金::PyOIDC可以从Keycloak检索提供者配置,因此无需为此进行手动输入。是的!

新设置 对于本地开发,我决定进行一些如下设置:

(1)添加到/etc/hosts127.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>"

(=)现在,您和Flask应用程序都可以访问keycloak.dev.local并可以进行适当的响应!

请注意,我仍然希望使用 nicer 解决方案。我的IP地址更改后,此设置就会失败。

1 个答案:

答案 0 :(得分:0)

flask-oidc从客户端密钥文件获取令牌端点配置。

我通过进行以下更改设法使它起作用:

  1. flask应用 keycloak 容器创建了一个docker网络;
  2. 编辑了属性 userinfo_uri token_uri token_introspection_uri ,将主机名替换为keycloak容器主机名(我正在使用docker-compose,在这种情况下,密钥斗篷容器的主机名就是服务名。

示例:

{
  "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网络连接以交换令牌信息。