File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -31,6 +31,7 @@ def __init__(
3131 claims = None ,
3232 token_placement = "header" ,
3333 scope = None ,
34+ client_id = None ,
3435 ** kwargs ,
3536 ):
3637 client_kwargs = extract_client_kwargs (kwargs )
@@ -47,6 +48,7 @@ def __init__(
4748 claims = claims ,
4849 token_placement = token_placement ,
4950 scope = scope ,
51+ client_id = client_id ,
5052 ** kwargs ,
5153 )
5254
@@ -88,6 +90,7 @@ def __init__(
8890 claims = None ,
8991 token_placement = "header" ,
9092 scope = None ,
93+ client_id = None ,
9194 ** kwargs ,
9295 ):
9396 client_kwargs = extract_client_kwargs (kwargs )
@@ -104,6 +107,7 @@ def __init__(
104107 claims = claims ,
105108 token_placement = token_placement ,
106109 scope = scope ,
110+ client_id = client_id ,
107111 ** kwargs ,
108112 )
109113
Original file line number Diff line number Diff line change @@ -39,6 +39,7 @@ def __init__(
3939 claims = None ,
4040 token_placement = "header" ,
4141 scope = None ,
42+ client_id = None ,
4243 default_timeout = None ,
4344 leeway = 60 ,
4445 ** kwargs ,
@@ -57,6 +58,7 @@ def __init__(
5758 claims = claims ,
5859 token_placement = token_placement ,
5960 scope = scope ,
61+ client_id = client_id ,
6062 leeway = leeway ,
6163 ** kwargs ,
6264 )
Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ def __init__(
2525 claims = None ,
2626 token_placement = "header" ,
2727 scope = None ,
28+ client_id = None ,
2829 leeway = 60 ,
2930 ** kwargs ,
3031 ):
@@ -46,6 +47,7 @@ def __init__(
4647 self .audience = audience
4748 self .claims = claims
4849 self .scope = scope
50+ self .client_id = client_id
4951 if self .token_auth_class is not None :
5052 self .token_auth = self .token_auth_class (None , token_placement , self )
5153 self ._kwargs = kwargs
@@ -79,6 +81,8 @@ def refresh_token(self):
7981 }
8082 if self .scope :
8183 data ["scope" ] = self .scope
84+ if self .client_id :
85+ data ["client_id" ] = self .client_id
8286
8387 return self ._refresh_token (data )
8488
Original file line number Diff line number Diff line change @@ -90,6 +90,9 @@ Version 1.7.0
9090- RFC7523 accepts the issuer URL as a valid audience. :issue: `730 `
9191- Fix ``InvalidTokenError `` extra attributes being wrapped instead of passed as
9292 individual key=value pairs in the ``WWW-Authenticate `` header. :pr: `872 `
93+ - Add optional ``client_id `` parameter to ``AssertionClient `` (and its
94+ ``AssertionSession `` / httpx wrappers) so it can be sent in the token
95+ endpoint request body per :rfc: `7521 ` §4.1 and :rfc: `6749 ` §3.2.1. :pr: `476 `
9396
9497Upgrade Guide: :ref: `joserfc_upgrade `.
9598
Original file line number Diff line number Diff line change @@ -52,6 +52,28 @@ def verifier(request):
5252 client .get ("https://provider.test" )
5353
5454
55+ def test_client_id ():
56+ """client_id is included in the token request body when provided."""
57+
58+ def verifier (request ):
59+ if str (request .url ) == "https://provider.test/token" :
60+ content = request .form
61+ assert "assertion" in content
62+ assert content ["client_id" ] == "my-client"
63+
64+ with AssertionClient (
65+ "https://provider.test/token" ,
66+ issuer = "foo" ,
67+ subject = "foo" ,
68+ audience = "foo" ,
69+ alg = "HS256" ,
70+ key = "secret" ,
71+ client_id = "my-client" ,
72+ transport = WSGITransport (MockDispatch (default_token , assert_func = verifier )),
73+ ) as client :
74+ client .get ("https://provider.test" )
75+
76+
5577def test_without_alg ():
5678 with AssertionClient (
5779 "https://provider.test/token" ,
Original file line number Diff line number Diff line change @@ -54,6 +54,29 @@ async def verifier(request):
5454 await client .get ("https://provider.test" )
5555
5656
57+ @pytest .mark .asyncio
58+ async def test_client_id ():
59+ """client_id is included in the token request body when provided."""
60+
61+ async def verifier (request ):
62+ if str (request .url ) == "https://provider.test/token" :
63+ content = await request .body ()
64+ assert b"assertion=" in content
65+ assert b"client_id=my-client" in content
66+
67+ async with AsyncAssertionClient (
68+ "https://provider.test/token" ,
69+ issuer = "foo" ,
70+ subject = "foo" ,
71+ audience = "foo" ,
72+ alg = "HS256" ,
73+ key = "secret" ,
74+ client_id = "my-client" ,
75+ transport = ASGITransport (AsyncMockDispatch (default_token , assert_func = verifier )),
76+ ) as client :
77+ await client .get ("https://provider.test" )
78+
79+
5780@pytest .mark .asyncio
5881async def test_without_alg ():
5982 async with AsyncAssertionClient (
You can’t perform that action at this time.
0 commit comments