Skip to content

Commit 2a288fd

Browse files
AndreaGrecon2ygk
authored andcommitted
OpenID: Claims: Add claims inside well-known
Some client can't use userinfo, and get propelty from claims. Add claims key inside well-known.
1 parent 4b13743 commit 2a288fd

File tree

5 files changed

+56
-21
lines changed

5 files changed

+56
-21
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,5 @@ pySilver
6666
Shaheed Haque
6767
Vinay Karanam
6868
Eduardo Oliveira
69+
Andrea Greco
6970
Dominik George

docs/oidc.rst

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,17 @@ required claims, eg ``iss``, ``aud``, ``exp``, ``iat``, ``auth_time`` etc),
245245
and the ``sub`` claim will use the primary key of the user as the value.
246246
You'll probably want to customize this and add additional claims or change
247247
what is sent for the ``sub`` claim. To do so, you will need to add a method to
248-
our custom validator::
249-
248+
our custom validator.
249+
Standard claim ``sub`` is included by default, to remove it override ``get_claim_list``::
250250
class CustomOAuth2Validator(OAuth2Validator):
251-
252-
def get_additional_claims(self, request):
253-
return {
254-
"sub": request.user.email,
255-
"first_name": request.user.first_name,
256-
"last_name": request.user.last_name,
257-
}
251+
def get_additional_claims(self):
252+
def get_user_email(request):
253+
return request.user.get_full_name()
254+
255+
# Element name, callback to obtain data
256+
claims_list = [ ("email", get_sub_cod),
257+
("username", get_user_email) ]
258+
return claims_list
258259

259260
.. note::
260261
This ``request`` object is not a ``django.http.Request`` object, but an

oauth2_provider/oauth2_validators.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -728,15 +728,24 @@ def _save_id_token(self, jti, request, expires, *args, **kwargs):
728728
def get_jwt_bearer_token(self, token, token_handler, request):
729729
return self.get_id_token(token, token_handler, request)
730730

731-
def get_oidc_claims(self, token, token_handler, request):
732-
# Required OIDC claims
733-
claims = {
734-
"sub": str(request.user.id),
735-
}
731+
def get_claim_list(self):
732+
def get_sub_code(request):
733+
return str(request.user.id)
734+
735+
list = [ ("sub", get_sub_code) ]
736736

737737
# https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
738-
claims.update(**self.get_additional_claims(request))
738+
add = self.get_additional_claims()
739+
list.extend(add)
740+
741+
return list
739742

743+
def get_oidc_claims(self, token, token_handler, request):
744+
data = self.get_claim_list()
745+
claims = {}
746+
747+
for k, call in data:
748+
claims[k] = call(request)
740749
return claims
741750

742751
def get_id_token_dictionary(self, token, token_handler, request):
@@ -889,5 +898,5 @@ def get_userinfo_claims(self, request):
889898
"""
890899
return self.get_oidc_claims(None, None, request)
891900

892-
def get_additional_claims(self, request):
893-
return {}
901+
def get_additional_claims(self):
902+
return []

oauth2_provider/views/oidc.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ def get(self, request, *args, **kwargs):
4545
signing_algorithms = [Application.HS256_ALGORITHM]
4646
if oauth2_settings.OIDC_RSA_PRIVATE_KEY:
4747
signing_algorithms = [Application.RS256_ALGORITHM, Application.HS256_ALGORITHM]
48+
49+
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
50+
validator = validator_class()
51+
oidc_claims = []
52+
for el, _ in validator.get_claim_list():
53+
oidc_claims.append(el)
54+
4855
data = {
4956
"issuer": issuer_url,
5057
"authorization_endpoint": authorization_endpoint,
@@ -57,6 +64,7 @@ def get(self, request, *args, **kwargs):
5764
"token_endpoint_auth_methods_supported": (
5865
oauth2_settings.OIDC_TOKEN_ENDPOINT_AUTH_METHODS_SUPPORTED
5966
),
67+
"claims_supported": oidc_claims,
6068
}
6169
response = JsonResponse(data)
6270
response["Access-Control-Allow-Origin"] = "*"

tests/test_oidc_views.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def test_get_connect_discovery_info(self):
2929
"subject_types_supported": ["public"],
3030
"id_token_signing_alg_values_supported": ["RS256", "HS256"],
3131
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
32+
"claims_supported": ["sub"],
3233
}
3334
response = self.client.get(reverse("oauth2_provider:oidc-connect-discovery-info"))
3435
self.assertEqual(response.status_code, 200)
@@ -55,6 +56,7 @@ def test_get_connect_discovery_info_without_issuer_url(self):
5556
"subject_types_supported": ["public"],
5657
"id_token_signing_alg_values_supported": ["RS256", "HS256"],
5758
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
59+
"claims_supported": ["sub"],
5860
}
5961
response = self.client.get(reverse("oauth2_provider:oidc-connect-discovery-info"))
6062
self.assertEqual(response.status_code, 200)
@@ -146,11 +148,21 @@ def test_userinfo_endpoint_bad_token(oidc_tokens, client):
146148
assert rsp.status_code == 401
147149

148150

151+
EXAMPLE_EMAIL = "[email protected]"
152+
153+
154+
def claim_user_email(request):
155+
return EXAMPLE_EMAIL
156+
157+
149158
@pytest.mark.django_db
150159
def test_userinfo_endpoint_custom_claims(oidc_tokens, client, oauth2_settings):
151160
class CustomValidator(OAuth2Validator):
152-
def get_additional_claims(self, request):
153-
return {"state": "very nice"}
161+
def get_additional_claims(self):
162+
return [
163+
("username", claim_user_email),
164+
("email", claim_user_email),
165+
]
154166

155167
oidc_tokens.oauth2_settings.OAUTH2_VALIDATOR_CLASS = CustomValidator
156168
auth_header = "Bearer %s" % oidc_tokens.access_token
@@ -161,5 +173,9 @@ def get_additional_claims(self, request):
161173
data = rsp.json()
162174
assert "sub" in data
163175
assert data["sub"] == str(oidc_tokens.user.pk)
164-
assert "state" in data
165-
assert data["state"] == "very nice"
176+
177+
assert "username" in data
178+
assert data["username"] == EXAMPLE_EMAIL
179+
180+
assert "email" in data
181+
assert data["email"] == EXAMPLE_EMAIL

0 commit comments

Comments
 (0)