From d2fc35f4f48cbafa8413e03ce681fed8e7ae7fa5 Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Thu, 7 Nov 2024 00:29:18 +0000 Subject: [PATCH 01/11] Enable broker support on Linux --- msal/__main__.py | 1 + msal/application.py | 9 ++++++++- sample/interactive_sample.py | 3 ++- setup.cfg | 6 ++++-- tests/broker-test.py | 3 ++- tests/test_e2e.py | 1 + 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/msal/__main__.py b/msal/__main__.py index 0c6c59f7..2ee982a6 100644 --- a/msal/__main__.py +++ b/msal/__main__.py @@ -300,6 +300,7 @@ def _main(): instance_discovery=instance_discovery, enable_broker_on_windows=enable_broker, enable_broker_on_mac=enable_broker, + enable_broker_on_linux=enable_broker, enable_pii_log=enable_pii_log, token_cache=global_cache, ) if not is_cca else msal.ConfidentialClientApplication( diff --git a/msal/application.py b/msal/application.py index 260d80e0..1d47e1ef 100644 --- a/msal/application.py +++ b/msal/application.py @@ -672,6 +672,7 @@ def _decide_broker(self, allow_broker, enable_pii_log): "allow_broker is deprecated. " "Please use PublicClientApplication(..., " "enable_broker_on_windows=True, " + "enable_broker_on_linux=True, " "enable_broker_on_mac=...)", DeprecationWarning) opted_in_for_broker = ( @@ -1921,7 +1922,7 @@ def __init__(self, client_id, client_credential=None, **kwargs): .. note:: - You may set enable_broker_on_windows and/or enable_broker_on_mac to True. + You may set enable_broker_on_windows and/or enable_broker_on_mac and/or enable_broker_on_linux to True. **What is a broker, and why use it?** @@ -1989,6 +1990,12 @@ def __init__(self, client_id, client_credential=None, **kwargs): This parameter defaults to None, which means MSAL will not utilize a broker. New in MSAL Python 1.31.0. + + :param boolean enable_broker_on_linux: + This setting is only effective if your app is running on Linux. + This parameter defaults to None, which means MSAL will not utilize a broker. + + New in MSAL Python 1.32.0. """ if client_credential is not None: raise ValueError("Public Client should not possess credentials") diff --git a/sample/interactive_sample.py b/sample/interactive_sample.py index 8c3f2df9..908ced3f 100644 --- a/sample/interactive_sample.py +++ b/sample/interactive_sample.py @@ -47,7 +47,8 @@ oidc_authority=os.getenv('OIDC_AUTHORITY'), # For External ID with custom domain #enable_broker_on_windows=True, # Opted in. You will be guided to meet the prerequisites, if your app hasn't already #enable_broker_on_mac=True, # Opted in. You will be guided to meet the prerequisites, if your app hasn't already - + #enable_broker_on_linux=True, # Opted in. You will be guided to meet the prerequisites, if your app hasn't already + token_cache=global_token_cache, # Let this app (re)use an existing token cache. # If absent, ClientApplication will create its own empty token cache ) diff --git a/setup.cfg b/setup.cfg index 33ec3f06..82246720 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,9 +62,11 @@ broker = # most existing MSAL Python apps do not have the redirect_uri needed by broker. # # We need pymsalruntime.CallbackData introduced in PyMsalRuntime 0.14 - pymsalruntime>=0.14,<0.18; python_version>='3.6' and platform_system=='Windows' + pymsalruntime>=0.14,<0.19; python_version>='3.6' and platform_system=='Windows' # On Mac, PyMsalRuntime 0.17+ is expected to support SSH cert and ROPC - pymsalruntime>=0.17,<0.18; python_version>='3.8' and platform_system=='Darwin' + pymsalruntime>=0.17,<0.19; python_version>='3.8' and platform_system=='Darwin' + # PyMsalRuntime 0.18+ is expected to support broker on Linux + pymsalruntime>=0.18,<0.19; python_version>='3.8' and platform_system=='Linux' [options.packages.find] exclude = diff --git a/tests/broker-test.py b/tests/broker-test.py index cdcc4817..e30bdc5d 100644 --- a/tests/broker-test.py +++ b/tests/broker-test.py @@ -39,7 +39,8 @@ _AZURE_CLI, authority="https://login.microsoftonline.com/organizations", enable_broker_on_mac=True, - enable_broker_on_windows=True) + enable_broker_on_windows=True, + enable_broker_on_linux=True) def interactive_and_silent(scopes, auth_scheme, data, expected_token_type): print("An account picker shall be pop up, possibly behind this console. Continue from there.") diff --git a/tests/test_e2e.py b/tests/test_e2e.py index a0796547..079b93ee 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -200,6 +200,7 @@ def _build_app(cls, http_client=http_client or MinimalHttpClient(), enable_broker_on_windows=broker_available, enable_broker_on_mac=broker_available, + enable_broker_on_linux=broker_available, ) def _test_username_password(self, From edf77b466d85ff313d3907b3947103decf005b11 Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Thu, 7 Nov 2024 00:33:22 +0000 Subject: [PATCH 02/11] update version number --- msal/application.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/msal/application.py b/msal/application.py index 1d47e1ef..63dc7196 100644 --- a/msal/application.py +++ b/msal/application.py @@ -22,7 +22,7 @@ # The __init__.py will import this. Not the other way around. -__version__ = "1.31.0" # When releasing, also check and bump our dependencies's versions if needed +__version__ = "1.32.0" # When releasing, also check and bump our dependencies's versions if needed logger = logging.getLogger(__name__) _AUTHORITY_TYPE_CLOUDSHELL = "CLOUDSHELL" @@ -1994,7 +1994,7 @@ def __init__(self, client_id, client_credential=None, **kwargs): :param boolean enable_broker_on_linux: This setting is only effective if your app is running on Linux. This parameter defaults to None, which means MSAL will not utilize a broker. - + New in MSAL Python 1.32.0. """ if client_credential is not None: @@ -2002,9 +2002,11 @@ def __init__(self, client_id, client_credential=None, **kwargs): # Using kwargs notation for now. We will switch to keyword-only arguments. enable_broker_on_windows = kwargs.pop("enable_broker_on_windows", False) enable_broker_on_mac = kwargs.pop("enable_broker_on_mac", False) + enable_broker_on_linux = kwargs.pop("enable_broker_on_linux", False) self._enable_broker = bool( enable_broker_on_windows and sys.platform == "win32" - or enable_broker_on_mac and sys.platform == "darwin") + or enable_broker_on_mac and sys.platform == "darwin" + or enable_broker_on_linux and sys.platform == "linux") super(PublicClientApplication, self).__init__( client_id, client_credential=None, **kwargs) From 3bf91114cdc1d8d45116058c5b25a8f984927b43 Mon Sep 17 00:00:00 2001 From: Dharshan BJ Date: Fri, 8 Nov 2024 16:44:00 -0800 Subject: [PATCH 03/11] Update sample/interactive_sample.py Co-authored-by: Ray Luo --- sample/interactive_sample.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sample/interactive_sample.py b/sample/interactive_sample.py index 908ced3f..e0f463cb 100644 --- a/sample/interactive_sample.py +++ b/sample/interactive_sample.py @@ -48,7 +48,6 @@ #enable_broker_on_windows=True, # Opted in. You will be guided to meet the prerequisites, if your app hasn't already #enable_broker_on_mac=True, # Opted in. You will be guided to meet the prerequisites, if your app hasn't already #enable_broker_on_linux=True, # Opted in. You will be guided to meet the prerequisites, if your app hasn't already - token_cache=global_token_cache, # Let this app (re)use an existing token cache. # If absent, ClientApplication will create its own empty token cache ) From caab4475d0eab706950cdb99fe6be8b679cfd8c7 Mon Sep 17 00:00:00 2001 From: Dharshan BJ Date: Fri, 8 Nov 2024 16:44:41 -0800 Subject: [PATCH 04/11] Update msal/application.py Co-authored-by: Ray Luo --- msal/application.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/msal/application.py b/msal/application.py index 63dc7196..537ad6ab 100644 --- a/msal/application.py +++ b/msal/application.py @@ -672,8 +672,7 @@ def _decide_broker(self, allow_broker, enable_pii_log): "allow_broker is deprecated. " "Please use PublicClientApplication(..., " "enable_broker_on_windows=True, " - "enable_broker_on_linux=True, " - "enable_broker_on_mac=...)", + "...)", DeprecationWarning) opted_in_for_broker = ( self._enable_broker # True means Opted-in from PCA From aa5c74c58681440892b67fefbd5fe100ad20078d Mon Sep 17 00:00:00 2001 From: Dharshan BJ Date: Fri, 8 Nov 2024 16:45:15 -0800 Subject: [PATCH 05/11] Update tests/broker-test.py Co-authored-by: Ray Luo --- tests/broker-test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/broker-test.py b/tests/broker-test.py index e30bdc5d..4af75abb 100644 --- a/tests/broker-test.py +++ b/tests/broker-test.py @@ -40,7 +40,8 @@ authority="https://login.microsoftonline.com/organizations", enable_broker_on_mac=True, enable_broker_on_windows=True, - enable_broker_on_linux=True) + enable_broker_on_linux=True, + ) def interactive_and_silent(scopes, auth_scheme, data, expected_token_type): print("An account picker shall be pop up, possibly behind this console. Continue from there.") From 6f52d28f6ffd179abcf70efc071efcab0d977471 Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Sat, 9 Nov 2024 00:55:05 +0000 Subject: [PATCH 06/11] revert back release version bump --- msal/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal/application.py b/msal/application.py index 537ad6ab..d4786bc6 100644 --- a/msal/application.py +++ b/msal/application.py @@ -22,7 +22,7 @@ # The __init__.py will import this. Not the other way around. -__version__ = "1.32.0" # When releasing, also check and bump our dependencies's versions if needed +__version__ = "1.31.0" # When releasing, also check and bump our dependencies's versions if needed logger = logging.getLogger(__name__) _AUTHORITY_TYPE_CLOUDSHELL = "CLOUDSHELL" From e2cc47e330a5be300a31ba4b0addc19caeedb6a2 Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Mon, 13 Jan 2025 23:49:28 +0000 Subject: [PATCH 07/11] address comments --- msal/broker.py | 1 + 1 file changed, 1 insertion(+) diff --git a/msal/broker.py b/msal/broker.py index 775475a7..d0bd944b 100644 --- a/msal/broker.py +++ b/msal/broker.py @@ -26,6 +26,7 @@ min_ver = { "win32": "1.20", "darwin": "1.31", + "linux": "1.32", }.get(sys.platform) if min_ver: raise ImportError( From 1965976a6f0a1c83fa8cc5aa08b9df4f47ead5c1 Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Mon, 13 Jan 2025 15:57:51 -0800 Subject: [PATCH 08/11] address comment --- msal/broker.py | 1 + 1 file changed, 1 insertion(+) diff --git a/msal/broker.py b/msal/broker.py index 775475a7..d0bd944b 100644 --- a/msal/broker.py +++ b/msal/broker.py @@ -26,6 +26,7 @@ min_ver = { "win32": "1.20", "darwin": "1.31", + "linux": "1.32", }.get(sys.platform) if min_ver: raise ImportError( From 46713ac76b93f21a7a234c40409cee4f024ca36f Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Tue, 14 Jan 2025 08:59:07 -0800 Subject: [PATCH 09/11] update approximate version hint --- msal/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal/application.py b/msal/application.py index c66cd20e..13cf4065 100644 --- a/msal/application.py +++ b/msal/application.py @@ -1951,7 +1951,7 @@ def __init__(self, client_id, client_credential=None, **kwargs): if your app is expected to run on Mac 2. installed broker dependency, - e.g. ``pip install msal[broker]>=1.31,<2``. + e.g. ``pip install msal[broker]>=1.32,<2``. 3. tested with ``acquire_token_interactive()`` and ``acquire_token_silent()``. From 703723132ff2b4093bdca849eafc1f23a04e552d Mon Sep 17 00:00:00 2001 From: Dharshan Birur Jayaprabhu Date: Fri, 24 Jan 2025 23:16:44 +0000 Subject: [PATCH 10/11] update --- msal/application.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/msal/application.py b/msal/application.py index c66cd20e..ed0a562c 100644 --- a/msal/application.py +++ b/msal/application.py @@ -701,7 +701,7 @@ def _decide_broker(self, allow_broker, enable_pii_log): def is_pop_supported(self): """Returns True if this client supports Proof-of-Possession Access Token.""" - return self._enable_broker + return self._enable_broker and sys.platform != "linux" def _decorate_scope( self, scopes, @@ -1573,10 +1573,14 @@ def _acquire_token_silent_from_cache_and_possibly_refresh_it( raise ValueError("auth_scheme is not supported in Cloud Shell") return self._acquire_token_by_cloud_shell(scopes, data=data) + is_ssh_cert_or_pop_request = ( + data.get("token_type") == "ssh-cert" or + data.get("token_type") == "pop" or + isinstance(auth_scheme, msal.auth_scheme.PopAuthScheme)) if self._enable_broker and account and account.get("account_source") in ( _GRANT_TYPE_BROKER, # Broker successfully established this account previously. None, # Unknown data from older MSAL. Broker might still work. - ): + ) and (sys.platform != "linux" or not is_ssh_cert_or_pop_request): from .broker import _acquire_token_silently response = _acquire_token_silently( "https://{}/{}".format(self.authority.instance, self.authority.tenant), @@ -1823,7 +1827,7 @@ def acquire_token_by_username_password( """ claims = _merge_claims_challenge_and_capabilities( self._client_capabilities, claims_challenge) - if self._enable_broker: + if self._enable_broker and sys.platform != "linux": from .broker import _signin_silently response = _signin_silently( "https://{}/{}".format(self.authority.instance, self.authority.tenant), @@ -2134,6 +2138,10 @@ def acquire_token_interactive( False ) and data.get("token_type") != "ssh-cert" # Work around a known issue as of PyMsalRuntime 0.8 self._validate_ssh_cert_input_data(data) + is_ssh_cert_or_pop_request = ( + data.get("token_type") == "ssh-cert" or + data.get("token_type") == "pop" or + isinstance(auth_scheme, msal.auth_scheme.PopAuthScheme)) if not on_before_launching_ui: on_before_launching_ui = lambda **kwargs: None if _is_running_in_cloud_shell() and prompt == "none": @@ -2142,7 +2150,7 @@ def acquire_token_interactive( return self._acquire_token_by_cloud_shell(scopes, data=data) claims = _merge_claims_challenge_and_capabilities( self._client_capabilities, claims_challenge) - if self._enable_broker: + if self._enable_broker and (sys.platform != "linux" or not is_ssh_cert_or_pop_request): if parent_window_handle is None: raise ValueError( "parent_window_handle is required when you opted into using broker. " @@ -2167,7 +2175,9 @@ def acquire_token_interactive( ) return self._process_broker_response(response, scopes, data) - if auth_scheme: + if isinstance(auth_scheme, msal.auth_scheme.PopAuthScheme) and sys.platform == "linux": + raise ValueError("POP is not supported on Linux") + elif auth_scheme: raise ValueError(self._AUTH_SCHEME_UNSUPPORTED) on_before_launching_ui(ui="browser") telemetry_context = self._build_telemetry_context( From 89ef887965c864b1bad66f0fa61ee42173e96011 Mon Sep 17 00:00:00 2001 From: Dharshan BJ Date: Mon, 17 Feb 2025 19:20:41 -0800 Subject: [PATCH 11/11] Update msal/application.py Co-authored-by: Ray Luo --- msal/application.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msal/application.py b/msal/application.py index a43545b2..bd11a2a2 100644 --- a/msal/application.py +++ b/msal/application.py @@ -1953,6 +1953,8 @@ def __init__(self, client_id, client_credential=None, **kwargs): if your app is expected to run on Windows 10+ * ``msauth.com.msauth.unsignedapp://auth`` if your app is expected to run on Mac + * ``ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id`` + if your app is expected to run on Linux, especially WSL 2. installed broker dependency, e.g. ``pip install msal[broker]>=1.32,<2``.