pyjwt icon indicating copy to clipboard operation
pyjwt copied to clipboard

PyJWKClient doesn't support custom SSL contexts

Open apastel opened this issue 1 year ago • 0 comments

PyJWKClient doesn't support custom SSL contexts when calling fetch_data() to get the JWK set.

Expected Result

get_signing_key_from_jwt() could accept a SSLContext as a parameter to support authorization servers that may require custom SSL configurations, for example a server in a test environment that uses self-signed certs or requires a custom CA bundle.

Actual Result

For example, attempting get_signing_key_from_jwt() in a test environment that uses self-signed certs raises urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)>

Monkeypatched Solution

from jwt import PyJWKClient

def get_signing_key(encoded_jwt):
    PyJWKClient.fetch_data = fetch_data_ssl_verify
    jwk_client = PyJWKClient("https://acme.auth.com")
    signing_key = jwk_client.get_signing_key_from_jwt(encoded_jwt)
    return signing_key.key

def fetch_data_ssl_verify(self):
    import urllib.request
    import json
    import ssl

    ctx = ssl.create_default_context()
    ctx.load_verify_locations(cafile="/opt/certs/rootCA.pem")
    with urllib.request.urlopen(self.uri, context=ctx) as response:
        return json.load(response)

get_signing_key(encoded_jwt)

As shown, it's possible to pass a context to urllib.request.urlopen to allow specifying a custom SSLContext to enable working with servers that might be in a development environment or otherwise non-conforming to the default SSL options.

apastel avatar Aug 03 '22 18:08 apastel