From 59079811cd03298a9323ac980b85e7e9206b7941 Mon Sep 17 00:00:00 2001 From: Ashok Kumar Ramakrishnan <83938949+ashok672@users.noreply.github.com> Date: Tue, 15 Jul 2025 16:20:11 -0700 Subject: [PATCH 1/6] Add claims challenge parameter in initiate_device_flow --- msal/application.py | 4 +++- msal/oauth2cli/oauth2.py | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/msal/application.py b/msal/application.py index 24ef91d7..5557e933 100644 --- a/msal/application.py +++ b/msal/application.py @@ -2326,7 +2326,7 @@ def _acquire_token_interactive_via_broker( auth_scheme=auth_scheme, **data) - def initiate_device_flow(self, scopes=None, **kwargs): + def initiate_device_flow(self, scopes=None, claims_challenge=None, **kwargs): """Initiate a Device Flow instance, which will be used in :func:`~acquire_token_by_device_flow`. @@ -2341,6 +2341,8 @@ def initiate_device_flow(self, scopes=None, **kwargs): flow = self.client.initiate_device_flow( scope=self._decorate_scope(scopes or []), headers={msal.telemetry.CLIENT_REQUEST_ID: correlation_id}, + claims_challenge=_merge_claims_challenge_and_capabilities( + self._client_capabilities, claims_challenge), **kwargs) flow[self.DEVICE_FLOW_CORRELATION_ID] = correlation_id return flow diff --git a/msal/oauth2cli/oauth2.py b/msal/oauth2cli/oauth2.py index 01b7fc34..d25b5434 100644 --- a/msal/oauth2cli/oauth2.py +++ b/msal/oauth2cli/oauth2.py @@ -305,7 +305,7 @@ class Client(BaseClient): # We choose to implement all 4 grants in 1 class grant_assertion_encoders = {GRANT_TYPE_SAML2: BaseClient.encode_saml_assertion} - def initiate_device_flow(self, scope=None, **kwargs): + def initiate_device_flow(self, scope=None, claims_challenge=None, **kwargs): # type: (list, **dict) -> dict # The naming of this method is following the wording of this specs # https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.1 @@ -323,8 +323,11 @@ def initiate_device_flow(self, scope=None, **kwargs): DAE = "device_authorization_endpoint" if not self.configuration.get(DAE): raise ValueError("You need to provide device authorization endpoint") + data = {"client_id": self.client_id, "scope": self._stringify(scope or [])} + if claims_challenge: + data["claims"] = claims_challenge resp = self._http_client.post(self.configuration[DAE], - data={"client_id": self.client_id, "scope": self._stringify(scope or [])}, + data=data, headers=dict(self.default_headers, **kwargs.pop("headers", {})), **kwargs) flow = json.loads(resp.text) From ece91b8e6921ffaa2d133fc946a472a180e73ee0 Mon Sep 17 00:00:00 2001 From: Ashok Kumar Ramakrishnan <83938949+ashok672@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:17:33 -0700 Subject: [PATCH 2/6] Update msal/application.py Co-authored-by: Ray Luo --- msal/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal/application.py b/msal/application.py index 5557e933..9f55f2e2 100644 --- a/msal/application.py +++ b/msal/application.py @@ -2326,7 +2326,7 @@ def _acquire_token_interactive_via_broker( auth_scheme=auth_scheme, **data) - def initiate_device_flow(self, scopes=None, claims_challenge=None, **kwargs): + def initiate_device_flow(self, scopes=None, *, claims_challenge=None, **kwargs): """Initiate a Device Flow instance, which will be used in :func:`~acquire_token_by_device_flow`. From 40f3c84073eadaed80404369081ef801334fafe1 Mon Sep 17 00:00:00 2001 From: Ashok Kumar Ramakrishnan <83938949+ashok672@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:18:17 -0700 Subject: [PATCH 3/6] Update msal/oauth2cli/oauth2.py Co-authored-by: Ray Luo --- msal/oauth2cli/oauth2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal/oauth2cli/oauth2.py b/msal/oauth2cli/oauth2.py index d25b5434..8541f034 100644 --- a/msal/oauth2cli/oauth2.py +++ b/msal/oauth2cli/oauth2.py @@ -305,7 +305,7 @@ class Client(BaseClient): # We choose to implement all 4 grants in 1 class grant_assertion_encoders = {GRANT_TYPE_SAML2: BaseClient.encode_saml_assertion} - def initiate_device_flow(self, scope=None, claims_challenge=None, **kwargs): + def initiate_device_flow(self, scope=None, *, data=None, **kwargs): # type: (list, **dict) -> dict # The naming of this method is following the wording of this specs # https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.1 From 0788b7d1588715a1824b1a40ff44e6a996925193 Mon Sep 17 00:00:00 2001 From: Ashok Kumar Ramakrishnan <83938949+ashok672@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:19:38 -0700 Subject: [PATCH 4/6] Update msal/application.py Co-authored-by: Ray Luo --- msal/application.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msal/application.py b/msal/application.py index 9f55f2e2..c58678ca 100644 --- a/msal/application.py +++ b/msal/application.py @@ -2341,8 +2341,8 @@ def initiate_device_flow(self, scopes=None, *, claims_challenge=None, **kwargs): flow = self.client.initiate_device_flow( scope=self._decorate_scope(scopes or []), headers={msal.telemetry.CLIENT_REQUEST_ID: correlation_id}, - claims_challenge=_merge_claims_challenge_and_capabilities( - self._client_capabilities, claims_challenge), + data={"claims": _merge_claims_challenge_and_capabilities( + self._client_capabilities, claims_challenge)}, **kwargs) flow[self.DEVICE_FLOW_CORRELATION_ID] = correlation_id return flow From 6f751312a58d67b2769fc9c7f945c71b88d4001e Mon Sep 17 00:00:00 2001 From: Ashok Kumar Ramakrishnan <83938949+ashok672@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:23:24 -0700 Subject: [PATCH 5/6] Update oauth2.py --- msal/oauth2cli/oauth2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msal/oauth2cli/oauth2.py b/msal/oauth2cli/oauth2.py index 8541f034..a9471e9c 100644 --- a/msal/oauth2cli/oauth2.py +++ b/msal/oauth2cli/oauth2.py @@ -323,9 +323,9 @@ def initiate_device_flow(self, scope=None, *, data=None, **kwargs): DAE = "device_authorization_endpoint" if not self.configuration.get(DAE): raise ValueError("You need to provide device authorization endpoint") - data = {"client_id": self.client_id, "scope": self._stringify(scope or [])} - if claims_challenge: - data["claims"] = claims_challenge + _data = {"client_id": self.client_id, "scope": self._stringify(scope or [])} + if isinstance(data, dict): + _data.update(data) resp = self._http_client.post(self.configuration[DAE], data=data, headers=dict(self.default_headers, **kwargs.pop("headers", {})), From 17dec56aac7b0ae9f7848b863a125883d21d09ad Mon Sep 17 00:00:00 2001 From: Ashok Kumar Ramakrishnan <83938949+ashok672@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:25:24 -0700 Subject: [PATCH 6/6] Update oauth2.py --- msal/oauth2cli/oauth2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal/oauth2cli/oauth2.py b/msal/oauth2cli/oauth2.py index a9471e9c..ef32ceaa 100644 --- a/msal/oauth2cli/oauth2.py +++ b/msal/oauth2cli/oauth2.py @@ -327,7 +327,7 @@ def initiate_device_flow(self, scope=None, *, data=None, **kwargs): if isinstance(data, dict): _data.update(data) resp = self._http_client.post(self.configuration[DAE], - data=data, + data=_data, headers=dict(self.default_headers, **kwargs.pop("headers", {})), **kwargs) flow = json.loads(resp.text)