Reputation: 1
I'm trying to send an HTTP GET request using Python Requests to an API that is requiring a Client Certificate. I'm passing in a PEM and Key file into the GET request using
session = requests.Session()
session.get('https://localhost/rest/containers/7uyeogzKQayw4mmQmcJb2Q/listeners', cert=('development.pem', 'development.key'))
When making this call, I'm using NGINX as the endpoint, I'm getting:
2017-10-07 21:18:16,874 - containerLogger - DEBUG - code:400 text:
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.12.1</center>
</body>
</html>
I've tested the same API using a POST request against the same endpoint using the same certificates and it is successful. I've validated the same GET using a browser (Firefox) successfully.
I'm currently trying to figure out why the POST is successful, but the GET is failing. I'm not having any luck in searching for an answer.
Not sure if this is due to requests or urllib3.
Versions:
Any help is greatly appreciated.
Cheers - Erik
Upvotes: 0
Views: 15898
Reputation: 849
I stumbled upon the same issue. Here is my solution:
response = requests.get(url, cert=(curr_cert, curr_key), verify=False)
print response.content
You were missing the trusted cert. Requests verifies SSL certificates for HTTPS requests, just like a web browser. By default, SSL verification is enabled, and Requests will throw a SSLError if it’s unable to verify the certificate (Just like in your case)
verify=False should resolve the issue
By setting verify=False, you will get warnings like the following:
InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
If you do want to verify ssl verification, the following should help:
response = requests.get(url, cert=(curr_cert, curr_key), verify=verify='/path/to/trustedcertfile')
print response.content
Upvotes: -1
Reputation: 2297
When you are creating a session = requests.Session()
the documentation requests that you have session.cert = '/path/to/client-cert.crt'
An easier way is to pass it as a tuple.
requests.get('https://localhost/rest/containers/7uyeogzKQayw4mmQmcJb2Q/listeners', cert=('/path/client.cert', '/path/client.key'))
Documentation Link
Upvotes: 2