SimpleJWT + Django + Auth0 = Unable to load PEM file issue

I’m using SimpleJWT in Django, and for the life of me I don’t know why I’m getting the following error when I try to call the API via postman passing a Bearer token.

I checked a million tutorials and StackOverflow threads and I’m at a loss. Any help appreciated!

Here’s my config snippet:

JWT_ISSUER = f"https://{AUTH0_DOMAIN}/"
JWT_AUDIENCE = "http://127.0.0.1"
JWKS_URL = f"https://{AUTH0_DOMAIN}/.well-known/jwks.json"

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": True,
    "UPDATE_LAST_LOGIN": True,
    "ALGORITHM": "RS256",
    "AUDIENCE": JWT_AUDIENCE,
    "ISSUER": JWT_ISSUER,
    "JWK_URL": JWKS_URL,
    "AUTH_HEADER_TYPES": "Bearer",
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
    "USER_ID_FIELD": "auth0_sub",
    "USER_ID_CLAIM": "sub",
    "JTI_CLAIM": None,
    "TOKEN_TYPE_CLAIM": None,
}    

Full error stack:

Internal Server Error: /api/
Traceback (most recent call last):
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/jwt/algorithms.py", line 205, in prepare_key
    key = load_pem_private_key(key, password=None, backend=default_backend())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, the provided password may be incorrect, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [<OpenSSLError(code=503841036, lib=60, reason=524556, reason_text=unsupported)>])

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/views.py", line 497, in dispatch
    self.initial(request, *args, **kwargs)
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/views.py", line 414, in initial
    self.perform_authentication(request)
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/views.py", line 324, in perform_authentication
    request.user
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/request.py", line 231, in user
    self._authenticate()
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework/request.py", line 384, in _authenticate
    user_auth_tuple = authenticator.authenticate(self)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework_simplejwt/authentication.py", line 49, in authenticate
    validated_token = self.get_validated_token(raw_token)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework_simplejwt/authentication.py", line 104, in get_validated_token
    return AuthToken(raw_token)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework_simplejwt/tokens.py", line 56, in __init__
    self.payload = token_backend.decode(token, verify=verify)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/rest_framework_simplejwt/backends.py", line 139, in decode
    return jwt.decode(
           ^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/jwt/api_jwt.py", line 93, in decode
    decoded = super(PyJWT, self).decode(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/jwt/api_jws.py", line 155, in decode
    self._verify_signature(payload, signing_input, header, signature,
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/jwt/api_jws.py", line 220, in _verify_signature
    key = alg_obj.prepare_key(key)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/diogo/Documents/pam/.venv/lib/python3.12/site-packages/jwt/algorithms.py", line 207, in prepare_key
    key = load_pem_public_key(key, backend=default_backend())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. MalformedFraming
1 Like

Hey there @ditorelo - Thanks for the detailed description of the issue.

Are you able to decode an example token you’re attempting to pass to your API at jwt.io? Does it look as expected? Feel free to share the decoded token here, omitting any sensitive data, if you’d like me to take a look.

1 Like

Yes, I have ,here it is

1 Like

Thanks for sharing! The token looks OK - I’ve unfortunately not seen this particular error before myself. A bit of a stab in the dark, but does using a different audience (non-localhost) like http://test-test-api endpoint give you the same error? Unfortunately, you’ll need to create a new API as you can’t update the identifier (audience) of an existing one.

1 Like

Mate, you’re a star.

Updated the below to my ACTUAL audiences, now I’m getting different issues:

JWT_AUDIENCE = "http://127.0.0.1:8000/api"

If I use the token from my initial post I get

{
    "detail": "User not found",
    "code": "user_not_found"
}

Which I half expected as those are not getting credentials for a specific user. Same goes for the Authentication API debugger.

If I log in with a user and try to get any of these two tokens

{
    "detail": "Given token not valid for any token type",
    "code": "token_not_valid",
    "messages": [
        {
            "token_class": "Auth0Token",
            "token_type": "access",
            "message": "Token is invalid or expired"
        }
    ]
}

Here’s the jwt.io result for access_token, which makes me thing I’m using the wrong thing given there’s no payload data.

I’m new to auth0, do I need to get the access token from somewhere else?

1 Like

How are you logging a user in? The access token you’re getting is opaque due to the lack of an audience param being passed in the authorization request. You’ll just need to include the audience param (API identifier) in however you’re authorizing users, and the resulting token should have an RS256 “alg” claim and be decoded at jwt.io. This token should then be able to be validated by your API :crossed_fingers:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.