我有一个 gunicorn + uvicorn + fastApi 堆栈。 (基本上,我使用的是 https://hub.docker.com/r/tiangolo/uvicorn-gunicorn-fastapi docker 镜像)。
我已经通过提供适当的 gunicorn 配置选项实现了基于 SSL 的身份验证:certfile、keyfile、ca_certs、cert_reqs。 它运行良好:用户必须提供客户端 SSL 证书才能进行 API 调用。
我现在需要做的是获取客户端证书数据并将其进一步传递(将其添加到请求 header )到我的应用程序中,因为它包含一些客户端凭据。
例如,我找到了一种使用 gunicorn worker 的方法,方法是覆盖 gunicorn.workers.sync.SyncWorker
: https://gist.github.com/jmvrbanac/089540b255d6b40ca555c8e7ee484c13 。
但是有没有办法使用 UvicornWorker
做同样的事情?我试图查看 UvicornWorker
的源代码,但没有找到实现它的方法。
我深入研究了 Uvicorn 源代码,据我所知,为了访问客户端 TLS 证书数据,我需要使用 python asyncio 库(https://docs.python.org/3/library/asyncio-eventloop.html)做一些技巧,可能使用服务器(https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.Server)类并覆盖一些 UvicornWorker
的方法。
不过,我仍然不太确定是否有可能达到预期的结果。
最佳答案
我最终在我的服务器前面设置了 nginx (Openresty) 并添加了一个脚本来获取客户端证书并将其放入 header 中。
这是我的 nginx 配置的一部分:
set_by_lua_block $client_cert {
local client_certificate = ngx.var.ssl_client_raw_cert
if (client_certificate ~= nil) then
client_certificate = string.gsub(client_certificate, "\n", "")
ngx.req.set_header("X-CLIENT-ID", client_certificate)
end
return client_certificate
}
也可以直接在 nginx 配置中从客户端证书中提取某些特定字段(如 CN、序列号等),但我决定进一步传递整个证书。
我的问题没有像我最初想要的那样使用 gunicorn 就解决了,但这是迄今为止我找到的唯一好的解决方案。
关于Python Uvicorn——获取SSL证书信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61632768/