When working with Django OAuth Toolkit, using OIDC if you supply openid as the scope in request you get a id_token with access token.
This ID Token can initially be used to identify the user you have got access token for and also create a session.
{
"aud": "audience",
"iat": 1681801110,
"at_hash": "hash of included access token",
"sub": "1",
"given_name": "Dushyant",
"preferred_username": "dsh",
"iss": "authEndpointurl",
"exp": 1681837110,
"auth_time": 1681567804,
"jti": "tokenid"
}
But I wish to modify the claims in this JWT ID Token, it reveals the primary key of the database of Authorization Server as the unique id of the user which i don't want in the claim called sub.
I want to use another unique key as the value of sub claim.
I tried overriding the response a Custom Backend:
class CustomOAuthBackend(OAuthLibCore):
def __init__(self, server):
super().__init__(server)
def create_token_response(self, request):
response_data = super().create_token_response(request)
#Modify the response here
return response_data
And added this as the Custom Backend in the settings.
"OAUTH2_BACKEND_CLASS":"pathto.CustomOAuthBackend",
I haven't written any modification code for the response here since the token here is already created When I am calling the original create_token_response.
I want to override it in a way that I can modify the claims dict, I am not sure where it is getting created. We get the id_token all prepared. I want to override the process of creating id_token and change sub claim value.
Let me know if any more information is required.
Update 1:
While looking for a possible solution, found oauth2_provider.oauth2_validators have methods get_oidc_claims() and get_id_token_dictionary() which looks like could lead to a possible solution. Figuring out how to use it.
There is a write up in the code
This method is OPTIONAL and is NOT RECOMMENDED.
finalize_id_tokenSHOULD be implemented instead. However, if you want a full control over the minting of theid_token, you MAY want to overrideget_id_tokeninstead of usingfinalize_id_token.
This write up talks about get_id_token() method. Going through the code I see that finalize_id_token() is the method where JWT is created from claims.
This method calls get_id_token_dictionary then this internally calls get_oidc_claims() then this calls get_claim_dict(request). get_claim_dict(request) only takes a request while others take token etc also. This method looks correct to override as this actually adds that sub claim to claims.
def get_claim_dict(self, request):
if self._get_additional_claims_is_request_agnostic():
claims = {"sub": lambda r: str(r.user.id)}
else:
claims = {"sub": str(request.user.id)}
# https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
if self._get_additional_claims_is_request_agnostic():
add = self.get_additional_claims()
else:
add = self.get_additional_claims(request)
claims.update(add)
return claims
I can get claims from this modify it and return the new updated claims.

I was able to do it by the same process I mentioned in the question. At the end I override
get_claim_dict(self, request)method.I override the get_claim_dict in OAuth2Validator. Add this validator as custom validator in django settings
"OAUTH2_VALIDATOR_CLASS": "pathTo.CustomOAuth2Validator",On decoding the JWT ID Token you will get the new value.