我需要获取传入请求的SSL证书,并检查此客户端是否可以访问此特定端点。发送请求的服务很好,我可以看到带有以下代码的证书:
from requests.packages.urllib3.contrib import pyopenssl as reqs
def https_cert_subject_alt_names(host, port):
"""Read subject domains in https cert from remote server"""
x509 = reqs.OpenSSL.crypto.load_certificate(
reqs.OpenSSL.crypto.FILETYPE_PEM,
reqs.ssl.get_server_certificate((host, port))
)
return x509.get_subject()
if __name__ == '__main__':
domains = https_cert_subject_alt_names(domain_name, 443)
print(domains)
我收到请求的烧瓶应用程序非常简单:
# -*- coding: utf-8 -*-
import logging
from flask import Flask, request
logger = logging.getLogger(__name__)
app = Flask(__name__)
@app.before_request
def before_request():
logger.debug(request.environ)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5001)
Nginx的配置是这样的,因此我应该在request.environ
中接收证书:
# Make the following two variables accessible to the application:
uwsgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
uwsgi_param SSL_CLIENT_RAW_CERT $ssl_client_raw_cert;
但是我在request.environ
中真正拥有的是:
{
'wsgi.version': (1, 0),
'wsgi.url_scheme': 'http',
'wsgi.input': < _io.BufferedReader name = 5 > ,
'wsgi.errors': < _io.TextIOWrapper name = '<stderr>'
mode = 'w'
encoding = 'UTF-8' > ,
'wsgi.multithread': False,
'wsgi.multiprocess': False,
'wsgi.run_once': False,
'werkzeug.server.shutdown': < function WSGIRequestHandler.make_environ. < locals > .shutdown_server at 0x7f84fc631400 > ,
'SERVER_SOFTWARE': 'Werkzeug/0.14.1',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': '',
'PATH_INFO': '/',
'QUERY_STRING': '',
'REMOTE_ADDR': '172.19.0.5',
'REMOTE_PORT': 50612,
'SERVER_NAME': '0.0.0.0',
'SERVER_PORT': '5001',
'SERVER_PROTOCOL': 'HTTP/1.1',
'HTTP_HOST': '192.168.0.10:5001',
'HTTP_USER_AGENT': 'python-requests/2.19.1',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
'HTTP_ACCEPT': '*/*',
'HTTP_CONNECTION': 'keep-alive',
'CONTENT_TYPE': 'application/json',
'werkzeug.request': < Request 'http://192.168.0.10:5001/' [GET] >
}
如您所见,那里没有证书信息。我这样在客户端应用中发出请求:
import requests
url = 'http://192.168.0.10:5001/'
headers = {'Content-Type': 'application/json'}
requests.get(url, headers=headers)
那么如何从Flask应用程序中获取SSL证书?