python - flask 的双向 ssl 身份验证

标签 python python-2.7 authentication ssl flask

我已经实现了 SSL 通信,其中客户端应用程序使用 flask 验证 SSL 服务器应用程序的身份。现在我希望 SSL 服务器应用程序验证 SSL 客户端应用程序的身份。 flask 可以吗?如何验证客户端证书?在第一次握手期间,客户端发送 CSR,作为响应,我发送回由自签名 CA 证书签名的证书。

但我还不清楚下一次通信时服务器将如何验证客户端。证书验证是否有任何回调。链接 Google groups说它不可能在 Flask 上进行 ssl 身份验证。为了做到这一点,需要使用像 apache、ngnix 这样的网络服务器。这是验证客户端的唯一方法吗?

我还想实现一件事,即我需要根据每个客户的证书来识别他们。 flask 甚至可以吗?

我的问题可能很幼稚,因为我对 flask 还不太熟悉

最佳答案

免责声明

在我开始之前,我会注意@Emanuel Ey 的评论。您需要考虑是否首先在生产或开发服务器上完成。例如;如果您使用的是 Apache WebServer,则可以从 Apache 完成 HTTPS 组件。唯一不同的做法是将证书详细信息作为选项传递,然后您的服务器应用程序将在应用程序本身内验证序列号。

有可能

但它可能的方式并不被认为是良好的编程习惯。不幸的是,它不能从 flask.request 访问,并且不能通过 Flask 包访问。但是,Flask 使用 Werkzeug,可以通过修补 werkzeug.serving 包来编写您的主要 Flask 代码。不建议这样做,因为您可能希望稍后更新 Flask 或 Werkzeug,并且您的补丁可能会损坏并需要重新分解。即从 0.9 到 1.0。

这提供了一个不使用 Web 服务器的解决方案。但我会推荐 Web 服务器/环境变量组合。这是更清洁且相对较好的做法。

我做了一些测试,看看这是否容易实现。我能够确认此方法可以使用最新的开发代码库“Werkzeug-0.10_devdev_20141223-py2.7”。

您可能需要验证在每个证书中找到的序列号(种子号)(甚至可能还有其他一些变量)。您可能知道,序列号对于每个证书都是唯一的,并且在证书生成过程中由您在服务器端确定。它有助于将其与客户端记录和证书信息(如果适用)一起存储,以便稍后验证客户端证书序列号。注意:它可能需要在十六进制和以 10 为底的十进制之间进行更改。

Werkzeug dev_2014122

我所做的是将以下选项添加到对 wrap_socket()werkzeug.serving.BaseWSGIServer.__init__ 调用中。

使用这些; server_side=True, ca_certs= '/etc/apache2/ssl/ca.pem', cert_reqs=ssl.CERT_REQUIRED

  • ca_certs:用这个来验证,这是用来生成客户端证书的CA证书)
  • ssl.CERT_REQUIRED:要求针对 ca_certs 验证客户端证书

注意:如果客户端证书未通过初始验证,您将无法获取客户端证书。它将是无。

然后在我的 Flask 测试类中我修补了 verify_request 在哪里

def verify_request(self, request, client_address):

cert = request.getpeercert(True)
raw = decoder.decode(cert)[0]
print "Serial Number of your certificate is: % " % str(raw[0][1])
# todo: do checks & if serial no is ok then return true
return True

werkzeug.serving.BaseWSGIServer.verify_request = verify_request

这证明这是可能的,但您可能需要调查 BaseWSGIServer 继承的 HTTPServer 类的请求处理程序,以找到更好的方法来进行回调或覆盖。

Werkzeug 0.9.X

如果您使用的是 Werkzeug 0.9.X,我假设您使用的是 import from OpenSSL import SSL。见代码片段 here .我没有测试过。

您可能对此版本感兴趣的一些电话是: - Context.set_verify(mode, callback) - Connection.get_peer_certificate()

澄清

我不明白的是您提到在第一次握手期间发送 CSR。如果这是您生成客户端证书的过程,您可能需要重新考虑如何在系统和环境的上下文中执行此操作。如果我能有更多的信息,我可以进一步评论..

此外,SSL/TLS 上下文中的“握手”通常是指首先使用现有证书创建安全连接的操作。握手后立即建立连接。

关于python - flask 的双向 ssl 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23262768/

相关文章:

python - 子进程中 `shell` 中的 `shell=True` 是否表示 `bash` ?

Python (3.4) 字典/树扁平化时未调用递归函数

python - Graphviz 重叠边缘标签

python - Django Rest Framework + Angular.js Web 应用程序中的用户身份验证

django - 从 backend.get_user 访问 request.session

python - 为什么 pickle 比 np.save 花费的时间长得多?

python - 列表行为异常

python-2.7 - Python Mechanize BrowserStateError

python - 如何计算 python 中字典中前 10 个最常见的值

python - 当详细 View 上的force_login() 时,Django Rest Framework 在单元测试中给出 302?