Skip to content

Commit 0dc1dc0

Browse files
committed
A resource server probably doesn't have a token endpoint but can have an endpoint that receives a DPOP token.
1 parent f3d0bca commit 0dc1dc0

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

src/idpyoidc/server/oauth2/add_on/dpop.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
from typing import Optional
55
from typing import Union
66

7-
from cryptojwt import JWS
87
from cryptojwt import as_unicode
8+
from cryptojwt import JWS
99
from cryptojwt.jwk.jwk import key_from_jwk_dict
1010
from cryptojwt.jws.jws import factory
1111

12+
from idpyoidc.message import Message
1213
from idpyoidc.message import SINGLE_OPTIONAL_STRING
1314
from idpyoidc.message import SINGLE_REQUIRED_INT
1415
from idpyoidc.message import SINGLE_REQUIRED_JSON
1516
from idpyoidc.message import SINGLE_REQUIRED_STRING
16-
from idpyoidc.message import Message
1717
from idpyoidc.metadata import get_signing_algs
1818
from idpyoidc.server.client_authn import BearerHeader
1919

@@ -130,6 +130,7 @@ def userinfo_post_parse_request(request, client_id, context, auth_info, **kwargs
130130
"""
131131
Expect http_info attribute in kwargs. http_info should be a dictionary
132132
containing HTTP information.
133+
This function is ment for DPoP-protected resources.
133134
134135
:param request:
135136
:param client_id:
@@ -179,26 +180,37 @@ def token_args(context, client_id, token_args: Optional[dict] = None):
179180
return token_args
180181

181182

183+
def _add_to_context(endpoint, algs_supported):
184+
_context = endpoint.upstream_get("context")
185+
_context.provider_info["dpop_signing_alg_values_supported"] = algs_supported
186+
_context.add_on["dpop"] = {"algs_supported": algs_supported}
187+
_context.client_authn_methods["dpop"] = DPoPClientAuth
188+
189+
182190
def add_support(endpoint: dict, **kwargs):
183-
# Pick one endpoint
184-
_endp_name = list(endpoint.keys())[0]
185-
_endp = endpoint[_endp_name]
186-
_endp.post_parse_request.append(token_post_parse_request)
191+
# Pick the token endpoint
192+
_endp = endpoint.get("token", None)
193+
if _endp:
194+
_endp.post_parse_request.append(token_post_parse_request)
195+
_added_to_context = False
187196

188197
_algs_supported = kwargs.get("dpop_signing_alg_values_supported")
189198
if not _algs_supported:
190199
_algs_supported = ["RS256"]
191200
else:
192201
_algs_supported = [alg for alg in _algs_supported if alg in get_signing_algs()]
193202

194-
_context = _endp.upstream_get("context")
195-
_context.provider_info["dpop_signing_alg_values_supported"] = _algs_supported
196-
_context.add_on["dpop"] = {"algs_supported": _algs_supported}
197-
_context.client_authn_methods["dpop"] = DPoPClientAuth
203+
if _endp:
204+
_add_to_context(_endp, _algs_supported)
205+
_added_to_context = True
198206

199207
for _dpop_endpoint in kwargs.get("dpop_endpoints", ["userinfo"]):
200208
_endpoint = endpoint.get(_dpop_endpoint, None)
201209
if _endpoint:
210+
if not _added_to_context:
211+
_add_to_context(_endp, _algs_supported)
212+
_added_to_context = True
213+
202214
_endpoint.post_parse_request.append(userinfo_post_parse_request)
203215

204216

@@ -214,12 +226,12 @@ def is_usable(self, request=None, authorization_token=None, http_headers=None):
214226
return False
215227

216228
def verify(
217-
self,
218-
request: Optional[Union[dict, Message]] = None,
219-
authorization_token: Optional[str] = None,
220-
endpoint=None, # Optional[Endpoint]
221-
get_client_id_from_token: Optional[Callable] = None,
222-
**kwargs,
229+
self,
230+
request: Optional[Union[dict, Message]] = None,
231+
authorization_token: Optional[str] = None,
232+
endpoint=None, # Optional[Endpoint]
233+
get_client_id_from_token: Optional[Callable] = None,
234+
**kwargs,
223235
):
224236
# info contains token and client_id
225237
info = BearerHeader._verify(

tests/private/token_jwks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"keys": [{"kty": "oct", "use": "enc", "kid": "code", "k": "vSHDkLBHhDStkR0NWu8519rmV5zmnm5_"}, {"kty": "oct", "use": "enc", "kid": "refresh", "k": "jEDC1HE6RGTPVIwnjIHwRKCS9OSltGee"}]}
1+
{"keys": [{"kty": "oct", "use": "enc", "kid": "code", "k": "vSHDkLBHhDStkR0NWu8519rmV5zmnm5_"}, {"kty": "oct", "use": "enc", "kid": "refresh", "k": "vrjoMrmgK8SmJJPc318zTxqG_tvBqF5l"}]}

tests/static/jwks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"keys": [{"kty": "RSA", "use": "sig", "kid": "YnNESFhyQjloMnYzV2VqRGR2a3VCblFLX2h4VGl3TDVlY3FUNkViUE90bw", "n": "2iMaDALTQolz4UaT--GhjriLMyNbrDGlIXxSmgRh17Cm3cuHiyPOIQv1pjZVg4ATU1aafxmFyTfrmtf56tPuJ8yqcNNZC8XadYPAw7PTW9g8GJgLtC8GURJ9GQZD6FYIE6YCou8fYo6yd4b99y2y_vsl06cm9xQnstfp6eyMkcgQyrmdmlbyeuXwvcxsxtGX61MTJtCp4VELmDctJiYP_bD7HNRPV7uqXDMNmWSY0TYL-tg0As4y8-w3wSwmtcfWhnQEraFT0-m4hBpEWHlouuFNXRQIrXbamKxeh6kJNO0wJN8fZ4Ovygf8sE4kEwBPfWO59wxDF7camTpDUqg29Q", "e": "AQAB"}, {"kty": "EC", "use": "sig", "kid": "aWhtalRSTDZmNmRTd1ZDNWZmY3ZGMTNqM1dnLVA2RjQyMi1CNGdOSUNKVQ", "crv": "P-256", "x": "Ww5XVT3CxYN88BpJDZGodRiar0qr8UvPFaRoqzyD1Io", "y": "w23EDFAvwe03NjL5NKtUXwxuVMFmEn3ecJOPbljiDkg"}]}
1+
{"keys": [{"kty": "RSA", "use": "sig", "kid": "YnNESFhyQjloMnYzV2VqRGR2a3VCblFLX2h4VGl3TDVlY3FUNkViUE90bw", "e": "AQAB", "n": "2iMaDALTQolz4UaT--GhjriLMyNbrDGlIXxSmgRh17Cm3cuHiyPOIQv1pjZVg4ATU1aafxmFyTfrmtf56tPuJ8yqcNNZC8XadYPAw7PTW9g8GJgLtC8GURJ9GQZD6FYIE6YCou8fYo6yd4b99y2y_vsl06cm9xQnstfp6eyMkcgQyrmdmlbyeuXwvcxsxtGX61MTJtCp4VELmDctJiYP_bD7HNRPV7uqXDMNmWSY0TYL-tg0As4y8-w3wSwmtcfWhnQEraFT0-m4hBpEWHlouuFNXRQIrXbamKxeh6kJNO0wJN8fZ4Ovygf8sE4kEwBPfWO59wxDF7camTpDUqg29Q"}, {"kty": "EC", "use": "sig", "kid": "aWhtalRSTDZmNmRTd1ZDNWZmY3ZGMTNqM1dnLVA2RjQyMi1CNGdOSUNKVQ", "crv": "P-256", "x": "Ww5XVT3CxYN88BpJDZGodRiar0qr8UvPFaRoqzyD1Io", "y": "w23EDFAvwe03NjL5NKtUXwxuVMFmEn3ecJOPbljiDkg"}]}

0 commit comments

Comments
 (0)