Skip to content

Commit bfbb452

Browse files
authored
Merge pull request #55 from ctriant/oauth-discovery
Support code_challenge_methods_supported
2 parents 24519cc + bd9c9b9 commit bfbb452

File tree

7 files changed

+33
-34
lines changed

7 files changed

+33
-34
lines changed

src/idpyoidc/message/oauth2/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ class ASConfigurationResponse(Message):
352352
"ui_locales_supported": OPTIONAL_LIST_OF_STRINGS,
353353
"op_policy_uri": SINGLE_OPTIONAL_STRING,
354354
"op_tos_uri": SINGLE_OPTIONAL_STRING,
355+
"code_challenge_methods_supported": OPTIONAL_LIST_OF_STRINGS,
355356
"revocation_endpoint": SINGLE_OPTIONAL_STRING,
356357
"introspection_endpoint": SINGLE_OPTIONAL_STRING,
357358
}

src/idpyoidc/message/oidc/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,8 @@ class ProviderConfigurationResponse(ResponseMessage):
898898
"frontchannel_logout_supported": SINGLE_OPTIONAL_BOOLEAN,
899899
"frontchannel_logout_session_required": SINGLE_OPTIONAL_BOOLEAN,
900900
"backchannel_logout_supported": SINGLE_OPTIONAL_BOOLEAN,
901-
"backchannel_logout_session_required": SINGLE_OPTIONAL_BOOLEAN
901+
"backchannel_logout_session_required": SINGLE_OPTIONAL_BOOLEAN,
902+
"code_challenge_methods_supported": OPTIONAL_LIST_OF_STRINGS,
902903
# "jwk_encryption_url": SINGLE_OPTIONAL_STRING,
903904
# "x509_url": SINGLE_REQUIRED_STRING,
904905
# "x509_encryption_url": SINGLE_OPTIONAL_STRING,

src/idpyoidc/server/oauth2/authorization.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ class Authorization(Endpoint):
348348
"request_object_encryption_alg_values_supported": claims.get_encryption_algs,
349349
"request_object_encryption_enc_values_supported": claims.get_encryption_encs,
350350
# "grant_types_supported": ["authorization_code", "implicit"],
351+
"code_challenge_methods_supported": ["S256"],
351352
"scopes_supported": [],
352353
}
353354
default_capabilities = {
@@ -1087,7 +1088,7 @@ def process_request(
10871088
:return: dictionary
10881089
"""
10891090

1090-
if isinstance(request, self.error_cls):
1091+
if "error" in request:
10911092
return request
10921093

10931094
_cid = request["client_id"]

src/idpyoidc/server/oidc/add_on/pkce.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def post_authn_parse(request, client_id, context, **kwargs):
5151
)
5252

5353
if "code_challenge_method" not in request:
54-
request["code_challenge_method"] = "plain"
54+
request["code_challenge_method"] = "S256"
5555

5656
if "code_challenge" in request and (
5757
request["code_challenge_method"]
@@ -140,7 +140,17 @@ def add_pkce_support(endpoint: Dict[str, Endpoint], **kwargs):
140140
token_endpoint.post_parse_request.append(post_token_parse)
141141

142142
code_challenge_methods = kwargs.get("code_challenge_methods", CC_METHOD.keys())
143-
143+
code_challenge_methods = list(
144+
set(code_challenge_methods).intersection(
145+
authn_endpoint._supports["code_challenge_methods_supported"]
146+
)
147+
)
148+
if not code_challenge_methods:
149+
raise ValueError(
150+
"Unsupported method: {}".format(
151+
", ".join(kwargs.get("code_challenge_methods", CC_METHOD.keys()))
152+
)
153+
)
144154
kwargs["code_challenge_methods"] = {}
145155
for method in code_challenge_methods:
146156
if method not in CC_METHOD:

src/idpyoidc/server/oidc/authorization.py

100755100644
Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,21 @@ class Authorization(authorization.Authorization):
7777
name = "authorization"
7878

7979
_supports = {
80-
"claims_parameter_supported": True,
81-
"encrypt_request_object_supported": False,
82-
"request_object_signing_alg_values_supported": claims.get_signing_algs,
83-
"request_object_encryption_alg_values_supported": claims.get_encryption_algs,
84-
"request_object_encryption_enc_values_supported": claims.get_encryption_encs,
85-
"request_parameter_supported": True,
86-
"request_uri_parameter_supported": True,
87-
"require_request_uri_registration": False,
88-
"response_types_supported": ["code", "token", "code token", 'id_token', 'id_token token',
80+
**authorization.Authorization._supports,
81+
**{
82+
"claims_parameter_supported": True,
83+
"encrypt_request_object_supported": False,
84+
"request_object_signing_alg_values_supported": claims.get_signing_algs,
85+
"request_object_encryption_alg_values_supported": claims.get_encryption_algs,
86+
"request_object_encryption_enc_values_supported": claims.get_encryption_encs,
87+
"request_parameter_supported": True,
88+
"request_uri_parameter_supported": True,
89+
"require_request_uri_registration": False,
90+
"response_types_supported": ["code", "token", "code token", 'id_token', 'id_token token',
8991
'code id_token', 'code id_token token'],
90-
"response_modes_supported": ['query', 'fragment', 'form_post'],
91-
"subject_types_supported": ["public", "pairwise", "ephemeral"],
92+
"response_modes_supported": ['query', 'fragment', 'form_post'],
93+
"subject_types_supported": ["public", "pairwise", "ephemeral"],
94+
},
9295
}
9396

9497
def __init__(self, upstream_get: Callable, **kwargs):

tests/test_08_transform.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ def test_oidc_setup(self):
117117
'service_documentation',
118118
'token_endpoint',
119119
'ui_locales_supported',
120-
'userinfo_endpoint'}
120+
'userinfo_endpoint',
121+
'code_challenge_methods_supported'}
121122

122123
# parameters that are not mapped against what the OP's provider info says
123124
assert set(self.supported).difference(

tests/test_server_33_oauth2_pkce.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -367,24 +367,6 @@ def test_unknown_code_challenge_method(self):
367367
_authn_req["code_challenge_method"]
368368
)
369369

370-
def test_unsupported_code_challenge_method(self, conf):
371-
conf["add_on"]["pkce"]["kwargs"]["code_challenge_methods"] = ["plain"]
372-
server = create_server(conf)
373-
authn_endpoint = server.get_endpoint("authorization")
374-
375-
_cc_info = _code_challenge()
376-
_authn_req = AUTH_REQ.copy()
377-
_authn_req["code_challenge"] = _cc_info["code_challenge"]
378-
_authn_req["code_challenge_method"] = _cc_info["code_challenge_method"]
379-
380-
_pr_resp = authn_endpoint.parse_request(_authn_req.to_dict())
381-
382-
assert isinstance(_pr_resp, AuthorizationErrorResponse)
383-
assert _pr_resp["error"] == "invalid_request"
384-
assert _pr_resp["error_description"] == "Unsupported code_challenge_method={}".format(
385-
_authn_req["code_challenge_method"]
386-
)
387-
388370
def test_wrong_code_verifier(self):
389371
_cc_info = _code_challenge()
390372
_authn_req = AUTH_REQ.copy()

0 commit comments

Comments
 (0)