Skip to content

Commit 4b34fd6

Browse files
authored
Merge pull request #85 from AzureAD/release-0.6.1
Release 0.6.1
2 parents bb80636 + 0e19bc6 commit 4b34fd6

File tree

4 files changed

+28
-11
lines changed

4 files changed

+28
-11
lines changed

msal/application.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919

2020
# The __init__.py will import this. Not the other way around.
21-
__version__ = "0.6.0"
21+
__version__ = "0.6.1"
2222

2323
logger = logging.getLogger(__name__)
2424

msal/oauth2cli/oidc.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,29 @@
44

55
from . import oauth2
66

7+
def decode_part(raw, encoding="utf-8"):
8+
"""Decode a part of the JWT.
79
8-
def base64decode(raw):
9-
"""A helper can handle a padding-less raw input"""
10+
JWT is encoded by padding-less base64url,
11+
based on `JWS specs <https://tools.ietf.org/html/rfc7515#appendix-C>`_.
12+
13+
:param encoding:
14+
If you are going to decode the first 2 parts of a JWT, i.e. the header
15+
or the payload, the default value "utf-8" would work fine.
16+
If you are going to decode the last part i.e. the signature part,
17+
it is a binary string so you should use `None` as encoding here.
18+
"""
1019
raw += '=' * (-len(raw) % 4) # https://stackoverflow.com/a/32517907/728675
11-
return base64.b64decode(raw).decode("utf-8")
20+
raw = str(
21+
# On Python 2.7, argument of urlsafe_b64decode must be str, not unicode.
22+
# This is not required on Python 3.
23+
raw)
24+
output = base64.urlsafe_b64decode(raw)
25+
if encoding:
26+
output = output.decode(encoding)
27+
return output
1228

29+
base64decode = decode_part # Obsolete. For backward compatibility only.
1330

1431
def decode_id_token(id_token, client_id=None, issuer=None, nonce=None, now=None):
1532
"""Decodes and validates an id_token and returns its claims as a dictionary.
@@ -19,7 +36,7 @@ def decode_id_token(id_token, client_id=None, issuer=None, nonce=None, now=None)
1936
and it may contain other optional content such as "preferred_username",
2037
`maybe more <https://openid.net/specs/openid-connect-core-1_0.html#Claims>`_
2138
"""
22-
decoded = json.loads(base64decode(id_token.split('.')[1]))
39+
decoded = json.loads(decode_part(id_token.split('.')[1]))
2340
err = None # https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
2441
if issuer and issuer != decoded["iss"]:
2542
# https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse

msal/token_cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import logging
55

66
from .authority import canonicalize
7-
from .oauth2cli.oidc import base64decode, decode_id_token
7+
from .oauth2cli.oidc import decode_part, decode_id_token
88

99

1010
logger = logging.getLogger(__name__)
@@ -124,7 +124,7 @@ def add(self, event, now=None):
124124
client_info = {}
125125
home_account_id = None # It would remain None in client_credentials flow
126126
if "client_info" in response: # We asked for it, and AAD will provide it
127-
client_info = json.loads(base64decode(response["client_info"]))
127+
client_info = json.loads(decode_part(response["client_info"]))
128128
home_account_id = "{uid}.{utid}".format(**client_info)
129129
elif id_token_claims: # This would be an end user on ADFS-direct scenario
130130
client_info["uid"] = id_token_claims.get("sub")

tests/test_assertion.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import json
22

3-
from msal.oauth2cli import JwtSigner
4-
from msal.oauth2cli.oidc import base64decode
3+
from msal.oauth2cli import JwtAssertionCreator
4+
from msal.oauth2cli.oidc import decode_part
55

66
from tests import unittest
77

88

99
class AssertionTestCase(unittest.TestCase):
1010
def test_extra_claims(self):
11-
assertion = JwtSigner(key=None, algorithm="none").sign_assertion(
11+
assertion = JwtAssertionCreator(key=None, algorithm="none").sign_assertion(
1212
"audience", "issuer", additional_claims={"client_ip": "1.2.3.4"})
13-
payload = json.loads(base64decode(assertion.split(b'.')[1].decode('utf-8')))
13+
payload = json.loads(decode_part(assertion.split(b'.')[1].decode('utf-8')))
1414
self.assertEqual("1.2.3.4", payload.get("client_ip"))
1515

0 commit comments

Comments
 (0)