-
Notifications
You must be signed in to change notification settings - Fork 27
Allow more robust JWT enrichment #29
Description
I would like a way to make a more robust JWT modeling some of the claims after OIDC (though not completely compliant). To do this I need access to user information. Currently the token_enricher
function is passed only the request
object but it doesn't contain any user information since the user is not logged in.
I propose passing all known information to the token_enricher
function and letting the user decide exactly what's included in the token. For example:
payload_enricher = getattr(settings, 'JWT_PAYLOAD_ENRICHER', None)
if payload_enricher:
fn = import_string(payload_enricher)
enriched_data = fn(
request=request,
token_content=content,
token_obj=token,
current_claims=extra_data)
if getattr(settings, 'JWT_PAYLOAD_ENRICHER_OVERWRITE', False):
extra_data = enriched_data
else:
extra_data.update(enriched_data)
This would allow for user functions that look more like this:
# myproject/myapp/jwt_utils.py
def payload_enricher(**kwargs):
# Keyword Args: request, token_content, token_obj, current_claims
# The Django HTTPRequest object
request = kwargs.pop('request', None)
# Dictionary of the content of the Oauth response. Includes values like
# access_token, expires_in, token_type, refresh_token, scope
content = kwargs.pop('token_content', None)
# The oauth2_provider access token (by default:
# oauth2_provider.models.AccessToken)
token = kwargs.pop('token_obj', None)
# The automatically generated claims. This usually includes your
# JWT_ID_ATTRIBUTE and scope. This can be useful if you want to use
# JWT_PAYLOAD_ENRICHER_OVERWRITE mode.
current_claims = kwargs.pop('current_claims', None)
# Values returned here must be serializable by json.dumps
return {
'sub': token.user.pk,
'preferred_username': token.user.username,
...
}
This implementation "works for me" but it may break backward compatibility with existing enrichment functions that accept a single named parameter (this should be fixed in the future by updating the documentation to accept **kwargs
as in the above example).
I've opened a pull request (#30) if this is something others would find value in.