Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A silenced error for JWT Stateless Authentication during token validation #832

Open
InterStella0 opened this issue Nov 28, 2024 · 0 comments

Comments

@InterStella0
Copy link

Context

I'm using Keycloak to implement SSO with Django, and I found this library. I used JWTStatelessUserAuthentication for my default authentication class as stated in the docs. However, i was having trouble with the validation process when the frontend passed in the JWT token to django on a protected endpoint. It keeps giving me 401 Unauthorized with the message "Token is invalid or expired". The message was quite vague as i couldn't debug the code as there is no logging output other than the Unauthorized response.

Issue

With Keycloak, you would get the JWK via https://xxx/realms/xxx/protocol/openid-connect/certs endpoint. What I found was that it was raising a Forbidden error from PyJWKClient when it does PyJWKClient.fetch_data(), I couldn't see this error due to the generic error raised by this try-except.

For more detail, Keycloak rejects (gives Forbidden) on GET requests that does not have a user-agent header, which PyJWKClient does not by default.

Current solution

To solve my issue i had to override Token and patch the token_backend

Code

from rest_framework_simplejwt.tokens import AccessToken
class KeycloakAccessToken(AccessToken):
    token_type = "Bearer"  # token_type is not stated within payload, but `typ` exist
    def get_token_backend(self) -> "TokenBackend":
        backend = super().get_token_backend()
        backend.jwks_client.headers = {"User-Agent": "Keycloak-python-urllib"}
        return backend

settings.py

SIMPLE_JWT = {
    "ALGORITHM": "RS256",
    "ISSUER": KEYCLOAK_ISSUER,
    "JWK_URL": JWKS_URL,
    "SIGNING_KEY": None,
    "VERIFYING_KEY": None,
    "USER_ID_CLAIM": "sub",
    "TOKEN_TYPE_CLAIM": "typ",
    "LEEWAY": 5,
    "AUTH_HEADER_TYPES": ("Bearer",),
    "AUTH_TOKEN_CLASSES": ("search.token.KeycloakAccessToken",),
}

Discussion

It would be helpful if there is a way to debug these, have verbose output with logging DEBUG level. It would also be good to be able to override PyJWKClient args for TokenBackend init.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant