Skip to content

Commit df07ffe

Browse files
authored
ConfidentialClientApplication(..., client_claims=...,) (#68)
1 parent 374e738 commit df07ffe

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

msal/application.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def __init__(
7272
self, client_id,
7373
client_credential=None, authority=None, validate_authority=True,
7474
token_cache=None,
75-
verify=True, proxies=None, timeout=None):
75+
verify=True, proxies=None, timeout=None,
76+
client_claims=None):
7677
"""Create an instance of application.
7778
7879
:param client_id: Your app has a client_id after you register it on AAD.
@@ -91,6 +92,22 @@ def __init__(
9192
public_certificate (optional) is public key certificate which is
9293
sent through 'x5c' JWT header only for
9394
subject name and issuer authentication to support cert auto rolls
95+
96+
:param dict client_claims:
97+
It is a dictionary of extra claims that would be signed by
98+
by this :class:`ConfidentialClientApplication` 's private key.
99+
For example, you can use {"client_ip": "x.x.x.x"}.
100+
You may also override any of the following default claims:
101+
102+
{
103+
"aud": the_token_endpoint,
104+
"iss": self.client_id,
105+
"sub": same_as_issuer,
106+
"exp": now + 10_min,
107+
"iat": now,
108+
"jti": a_random_uuid
109+
}
110+
94111
:param str authority:
95112
A URL that identifies a token authority. It should be of the format
96113
https://login.microsoftonline.com/your_tenant
@@ -115,6 +132,7 @@ def __init__(
115132
"""
116133
self.client_id = client_id
117134
self.client_credential = client_credential
135+
self.client_claims = client_claims
118136
self.verify = verify
119137
self.proxies = proxies
120138
self.timeout = timeout
@@ -140,7 +158,8 @@ def _build_client(self, client_credential, authority):
140158
client_credential["private_key"], algorithm="RS256",
141159
sha1_thumbprint=client_credential.get("thumbprint"), headers=headers)
142160
client_assertion = signer.sign_assertion(
143-
audience=authority.token_endpoint, issuer=self.client_id)
161+
audience=authority.token_endpoint, issuer=self.client_id,
162+
additional_claims=self.client_claims or {})
144163
client_assertion_type = Client.CLIENT_ASSERTION_TYPE_JWT
145164
else:
146165
default_body['client_secret'] = client_credential

tests/test_assertion.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import json
2+
3+
from msal.oauth2cli import JwtSigner
4+
from msal.oauth2cli.oidc import base64decode
5+
6+
from tests import unittest
7+
8+
9+
class AssertionTestCase(unittest.TestCase):
10+
def test_extra_claims(self):
11+
assertion = JwtSigner(key=None, algorithm="none").sign_assertion(
12+
"audience", "issuer", additional_claims={"client_ip": "1.2.3.4"})
13+
payload = json.loads(base64decode(assertion.split(b'.')[1].decode('utf-8')))
14+
self.assertEqual("1.2.3.4", payload.get("client_ip"))
15+

0 commit comments

Comments
 (0)