Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion msal/oauth2cli/assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@

logger = logging.getLogger(__name__)


def _str2bytes(raw):
# A conversion based on duck-typing rather than six.text_type
try: # Assuming it is a string
return raw.encode(encoding="utf-8")
except: # Otherwise we treat it as bytes and return it as-is
return raw


class AssertionCreator(object):
def create_normal_assertion(
self, audience, issuer, subject, expires_at=None, expires_in=600,
Expand Down Expand Up @@ -103,8 +112,9 @@ def create_normal_assertion(
payload['nbf'] = not_before
payload.update(additional_claims or {})
try:
return jwt.encode(
str_or_bytes = jwt.encode( # PyJWT 1 returns bytes, PyJWT 2 returns str
payload, self.key, algorithm=self.algorithm, headers=self.headers)
return _str2bytes(str_or_bytes) # We normalize them into bytes
except:
if self.algorithm.startswith("RS") or self.algorithm.starswith("ES"):
logger.exception(
Expand Down
8 changes: 5 additions & 3 deletions msal/oauth2cli/oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ def __init__(
client_secret (str): Triggers HTTP AUTH for Confidential Client
client_assertion (bytes, callable):
The client assertion to authenticate this client, per RFC 7521.
It can be a raw SAML2 assertion (this method will encode it for you),
or a raw JWT assertion.
It can be a raw SAML2 assertion (we will base64 encode it for you),
or a raw JWT assertion in bytes (which we will relay to http layer).
It can also be a callable (recommended),
so that we will do lazy creation of an assertion.
client_assertion_type (str):
Expand Down Expand Up @@ -198,7 +198,9 @@ def _obtain_token( # The verb "obtain" is influenced by OAUTH2 RFC 6749
self.default_body["client_assertion_type"], lambda a: a)
_data["client_assertion"] = encoder(
self.client_assertion() # Do lazy on-the-fly computation
if callable(self.client_assertion) else self.client_assertion)
if callable(self.client_assertion) else self.client_assertion
) # The type is bytes, which is preferrable. See also:
# https://github.com/psf/requests/issues/4503#issuecomment-455001070

_data.update(self.default_body) # It may contain authen parameters
_data.update(data or {}) # So the content in data param prevails
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
# See https://stackoverflow.com/a/14211600/728675 for more detail
install_requires=[
'requests>=2.0.0,<3',
'PyJWT[crypto]>=1.0.0,<2',
'PyJWT[crypto]>=1.0.0,<3',

'cryptography>=0.6,<4',
# load_pem_private_key() is available since 0.6
Expand Down