djangorestframework-simplejwt with auth0 - settings issue?

890 Views Asked by At

environment:

  • django (4.0.4)
  • rest_framework (3.13.1)
  • djangorestframework-simplejwt (5.2.0)

What are the exact settings that should be used with simplejwt+auth0? I cannot find any example and unfortunately i've failed to figure it out by myself.

I have tried the following:

AUTH0_DOMAIN = 'dev-demo-xxxx.auth0.com'
API_IDENTIFIER = 'xxxxx'
PUBLIC_KEY = None
JWT_ISSUER = None

if AUTH0_DOMAIN:
    jsonurl = request.urlopen('https://' + AUTH0_DOMAIN + '/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read().decode('utf-8'))
    cert = '-----BEGIN CERTIFICATE-----\n' + jwks['keys'][0]['x5c'][0] + '\n-----END CERTIFICATE-----'
    certificate = load_pem_x509_certificate(cert.encode('utf-8'), default_backend())
    PUBLIC_KEY = certificate.public_key()
    JWT_ISSUER = 'https://' + AUTH0_DOMAIN + '/'


SIMPLE_JWT = {
    'ALGORITHM': 'RS256',
    'AUDIENCE': 'https://issuer-domain',
    'ISSUER': JWT_ISSUER,
    'VERIFYING_KEY': PUBLIC_KEY
}

but tokens that are sent from client (retrieved successfully using auth0 javascript library) are not verified properly on the backend. (token has been successfully verified using jwt.io debugging tool)

current error:

code: "token_not_valid"
detail: "Given token not valid for any token type"
2

There are 2 best solutions below

1
JonDoe297 On

These are the settings which worked for me today:

AUTH0_DOMAIN = "YOUR_DOMAIN"
AUTH0_AUDIENCE = "YOUR_AUDIENCE"

SIMPLE_JWT = {
    'ALGORITHM': 'RS256',
    'AUDIENCE': AUTH0_AUDIENCE,
    'ISSUER': f"https://{AUTH0_DOMAIN}/",
    'JWK_URL': f"https://{AUTH0_DOMAIN}/.well-known/jwks.json",
    "USER_ID_CLAIM": f"{AUTH0_AUDIENCE}/email",
    'JTI_CLAIM': None,
    'TOKEN_TYPE_CLAIM': None,
}

Dependencies:

django==3.2.15
djangorestframework==3.11.2
djangorestframework-simplejwt[crypto]==5.2.0
authlib==1.0.1
0
samoz On

I was able to get Auth0 working with Django 4.1.3 and djangorestframework-simplejwt 5.2.2 using the configuration below.

The key areas that were tripping me up were the USER_ID_FIELD and USER_ID_CLAIM keys.

USER_ID_CLAIM is the value that is inside the JWT. You can confirm what is in yours with a JWT token debugger. Auth0 should include a sub field (for the unique user ID subclaim and should look like auth0|1234..), which is probably what you want to use for USER_ID_CLAIM. You can add additional data to the JWT with custom claims, but I didn't go that far.

USER_ID_FIELD is the column in your database to correlate with the value that is received in USER_ID_CLAIM. In my case, I store the Auth0 user ID values in a subclaim column, so that's what I put.

SIMPLE_JWT = {
    'ALGORITHM': 'RS256',
    'AUDIENCE': API_IDENTIFIER,
    'ISSUER': f"https://{AUTH0_DOMAIN}/",
    'JWK_URL': f"https://{AUTH0_DOMAIN}/.well-known/jwks.json",
    'USER_ID_FIELD': 'subclaim',
    'USER_ID_CLAIM': 'sub',
    'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'JTI_CLAIM': None,
    'TOKEN_TYPE_CLAIM': None,
}

Another note is that you can use the JWK_URL field to remove the need to manually parse out certificates, run the code under the if AUTH0_DOMAIN: block, or specify VERIFYING_KEY