python - 使用 keycloak 进行 flask 应用程序 OAuth 登录的 ssl.SSLCertVerificationError

标签 python ssl flask kubernetes keycloak

我从 https://gist.github.com/thomasdarimont/145dc9aa857b831ff2eff221b79d179a 引用了一个与 key-cloak 登录集成的示例 hello-world flask 应用程序。
我的 client-secrets.json 如下:

{
    "web": {
        "issuer": "https://keycloak-keycloak.router.default.svc.cluster.local.167.254.224.26.nip.io/auth/realms/myrealm",
        "auth_uri": "https://keycloak-keycloak.router.default.svc.cluster.local.167.254.224.26.nip.io/auth/realms/myrealm/protocol/openid-connect/auth",
        "client_id": "myclient",
        "client_secret": "****",
        "redirect_uris": [
            "https://167.254.224.26:30397/*"
        ],
        "userinfo_uri": "https://keycloak-keycloak.router.default.svc.cluster.local.167.254.224.26.nip.io/auth/realms/myrealm/protocol/openid-connect/userinfo",
        "token_uri": "https://keycloak-keycloak.router.default.svc.cluster.local.167.254.224.26.nip.io/auth/realms/myrealm/protocol/openid-connect/token",
        "token_introspection_uri": "https://keycloak-keycloak.router.default.svc.cluster.local.167.254.224.26.nip.io/auth/realms/myrealm/protocol/openid-connect/token/introspect"
    }
}

当我运行 python app.py它运行成功,但是一旦我浏览应用程序 url 并单击登录,它会带我进入 keyclock 登录页面,在我输入我的凭据后,我收到以下错误
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/flask_oidc/__init__.py", line 657, in _oidc_callback
    plainreturn, data = self._process_callback('destination')
  File "/usr/local/lib/python3.7/site-packages/flask_oidc/__init__.py", line 689, in _process_callback
    credentials = flow.step2_exchange(code)
  File "/usr/local/lib/python3.7/site-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/oauth2client/client.py", line 2054, in step2_exchange
    http, self.token_uri, method='POST', body=body, headers=headers)
  File "/usr/local/lib/python3.7/site-packages/oauth2client/transport.py", line 282, in request
    connection_type=connection_type)
  File "/usr/local/lib/python3.7/site-packages/httplib2/__init__.py", line 1994, in request
    cachekey,
  File "/usr/local/lib/python3.7/site-packages/httplib2/__init__.py", line 1651, in _request
    conn, request_uri, method, body, headers
  File "/usr/local/lib/python3.7/site-packages/httplib2/__init__.py", line 1557, in _conn_request
    conn.connect()
  File "/usr/local/lib/python3.7/site-packages/httplib2/__init__.py", line 1326, in connect
    self.sock = self._context.wrap_socket(sock, server_hostname=self.host)
  File "/usr/local/lib/python3.7/ssl.py", line 423, in wrap_socket
    session=session
  File "/usr/local/lib/python3.7/ssl.py", line 870, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.7/ssl.py", line 1139, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1091)

我怀疑这可能是由于我的 key-cloack 服务器是 https 而 flask 应用程序是 http,因此我已经修改了 app.py成为https:
app.run(host='0.0.0.0', port=8000, debug=True, ssl_context='adhoc')
但即使在制作 flask 应用程序 https 之后,问题仍然存在。
请注意,由于我在容器中运行此应用程序,因此我已将 8000 端口暴露给 Nodeport,即 30397,因此应用程序 url 为:https://167.254.224.26:30397

最佳答案

那是 problem of flask-oidc .它使用 httplib2,它提供 disable_ssl_certificate_validation禁用 ssl/tls 证书验证的选项,但不幸的是,它不能从 flask-oidc 配置。
唯一的选择是添加用于为 https://keycloak-keycloak.router.default.svc.cluster.local.167.254.224.26.nip.io 创建 TLS 证书的 CA 证书。到 httplib2 ca 证书:

cat ca-cert.crt >> [path_to_python_libs]/certifi/cacert.pem
题外话:你的部署看起来像 Kubernetes,所以应该很容易得到 ca-cert.crt从集群中复制并在应用程序启动时将其复制到正确的位置。

关于python - 使用 keycloak 进行 flask 应用程序 OAuth 登录的 ssl.SSLCertVerificationError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65151766/

相关文章:

python - 是否有与正则表达式的 Perl "/x"修饰符等效的 Python?

python - 如何按django中的计算值排序

ssl - 使用现有私钥创建 CSR

java - 如何在 wso2product 上将 TLS 1.0 升级到 TLS 1.2

ruby-on-rails - 如何使用 rails-ssl 需求插件在 rails 中的 https 页面中使用 http 参数

javascript - Flask - Javascript 和 CSS 未正确呈现

python - 导入错误 : No module named flask. ext.security.datastore.SQLAlchemyUserDatastore

python - 为什么在名称前面有双下划线时传递关键字/命名参数会产生错误?

python - Pandas 根据日期范围 +/- x 天进行计数和求和

json - 如何 `jsonify` Flask 中的列表?