目标:

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

背景:

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

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

  • 运行Flask应用程序(端口5000)的Gunicorn
  • Keycloak(端口8080)

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

    问题:
  • 启动所有服务
  • 导航到需要登录的服务(示例中为/private)
  • 用户被重新路由到Keycloud服务器,提示登录。
  • 用户登录。
  • Keycloak将用户引导回应用程序(/oidc_callback)
  • !!! Flask应用因OSError: [Errno 99] Cannot assign requested address错误而崩溃。

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

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

    我尝试了什么:

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

    这向我显示了我的所有设置和代码都很好,但是问题出在Docker flask_oidc +之间的交互中。

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

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

    在自己的计算机(localhost)上在Docker中运行这两个服务时,您会遇到冲突:
  • 用户转到localhost:8080查找Keycloak,然后转到localhost:5000查找该应用程序。
  • 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>"
    (=)现在,您和Flask应用程序都可以访问keycloak.dev.local并可以正确响应!

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

    最佳答案

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

    我设法通过进行以下更改使其工作:

  • flask应用程序 keycloak 容器创建了一个docker网络;
  • 编辑了属性 userinfo_uri token_uri token_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网络连接以交换 token 信息。

    关于python - Flask_oidc在Docker容器中运行时给出 `Errno 99 Cannot assign requested address`,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53613866/

    10-16 10:15