Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broker integration #415

Merged
merged 8 commits into from
Oct 7, 2022
Merged

Broker integration #415

merged 8 commits into from
Oct 7, 2022

Conversation

rayluo
Copy link
Collaborator

@rayluo rayluo commented Oct 1, 2021

What is this?

A broker is a component installed on your device. Broker implicitly gives your device an identity. By using a broker, your device becomes a factor that can satisfy MFA (Multi-factor authentication). This factor would become mandatory if/when a tenant's admin enables a corresponding Conditional Access (CA) policy. The broker's presence allows Microsoft identity platform to have higher confidence that the tokens are being issued to your device, and that is more secure.

An additional benefit of broker is, it runs as a long-lived process with your device's OS, and maintains its own cache, so that your broker-enabled apps (even CLI) could automatically SSO from a previously established signed-in session.

Currently, broker is available on recent Windows platforms.

In this PR, MSAL Python utilizes the broker to acquire tokens. When enabled, broker behaviors will kick in when your PublicClientApplication app calls MSAL Python's acquire_token_interactive(), acquire_token_by_username_password(), acquire_token_silent(), acquire_token_silent_with_error(). Most noticeably, the acquire_token_interactive([...], prompt="select_account") will trigger a pop-up window, rather than a browser.

API reference docs has also been updated and staged at here (you would need to scroll up a little bit).

Prerequisite for an app

  1. Because this feature branch is not yet officially released with a version number, you will need to clean up your test environment by pip uninstall msal pymsalruntime -y, especially when you want to reset your test environment to test the latest changes in this PR.

  2. Use a recent version of MSAL Python.
    Currently, this can be achieved by installing the MSAL Python from this feature branch:
    pip install "git+https://github.com/AzureAD/microsoft-authentication-library-for-python.git@wam"

  3. Install the broker package.
    The broker package pymsalruntime needs to be available in your Python environment, so that MSAL Python will automatically utilize it. This can be satisfied by pip install "msal[broker] @ git+https://github.com/AzureAD/microsoft-authentication-library-for-python.git@wam". In the future (after this PR is merged and shipped), your app can meet the two prerequisites above by a simpler pip install "msal[broker]>=1.19,<2" (The actual release version is not yet determined.).
    (We do NOT recommend directly install pymsalruntime, because its latest version may not have been tested with MSAL Python. Stick with the installation command above so that you will always get the latest version of pymsalruntime which has been tested with MSAL Python.)

  4. Register one more redirect URI.
    Your app would need to register this one more redirect_uri beforehand, in this form: ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id.

  5. Opt-in.
    Currently, MSAL Python does not provide an API-level opt-in flag. App developer opts in by declaring needed dependencies AND registering a new redirect URL. Once all prerequisites are met, broker behavior will kick in, otherwise, it will gracefully be fallback to use non-broker behavior. The idea is your app does not need to hardcode your opt-in/opt-out decision, or to implement an opt-in or opt-out setting. The broker functionality can be toggled flexibly, without any source code changes to your app. This approach would make the adoption easier.
    Opt-in by PublicClientApplication(..., allow_broker=True).

Action items for a downstream library

  • As a library, the prerequisite No. 3 is not applicable to you
  • You do not need any source code changes to your library. You would need to somehow expose prerequisite No.4 allow_broker=True or False to your app developers.
  • There is also one new optional parameter acquire_token_interactive(..., window=...). It is documented here.
  • Optionally, you may consider also expose a [broker] option which internally makes dependency on msal[broker], so that your downstream apps could use pip install YourLibrary[broker] to pull in the dependencies for Microsoft identity platform's broker behavior. Or you simply declare msal[broker]... as a required dependency.

Regardless, you would still want to use your own test app to test the broker behavior to understand its impact on your library's experience.

What/How to test

  • Test script is available for download here and then run it by python msaltest.py.
    (Alternatively, you can use this MSAL Python's interactive sample, add the allow_broker=True flag, and then uncomment this line, to force a broker-powered pop-up window for authentication. Without changing that line, broker would still work, but it would silently use your already-signed-in account in your subsequent test runs, so it will be less tangible.)

  • Test this statement: "When an app does not yet register the broker-specific redirect_uri set allow_broker=True, installing the new MSAL Python and the broker package pymsalruntime should not cause authentication failure".

    1. Use recent MSAL Python 2. Install dependency (The environment contains pymsalruntime) 3. App registers a new redirect_uri 4. Opt-in Expected behavior (The behaviors implemented in this PR)
    No (i.e. using msal<=1.18) * * * This is the status quo without broker. We use this as a baseline.
    Yes (i.e. using this PR) * * False App should behave the same as before (i.e. above).
    Yes (i.e. using this PR) No * True App should behave the same as before (i.e. above). Exception will be raised
    Yes (i.e. using this PR) Yes No True MSAL would attempt broker, detect the error, emit a warning currently (but we could choose to remove that warning in next commit), and then fall back to use browser/AAD directly and raise an exception
    Yes (i.e. using this PR) Yes Yes True MSAL would use broker. Token or error would be returned to the app. More on this below.
  • In particular, when using acquire_token_interactive(..., prompt="select_account"), see if you would find any behavior difference between enabling and disabling broker.

    allow_broker=False allow_broker=True Comment
    Successfully obtained an AT Successfully obtained an AT This is the happy path
    Successfully obtained an AT Error out If your app has not met the prerequisite, some errors are expected. That being said, if you encounter some misleading error message, please report back to us.
    Error out Error out Generally we recommend you to get your app working without broker first. That being said, if you encounter some misleading error message in either case, please report back to us.

To report an issue, please share with us your test configuration. For example, you can do that by copy and paste the console history of your interaction with our test script python msaltest.py.

  • Test your app/library can work without a Refresh Token (RT)

    Another subtle change is the absence of refresh token (RT). When an acquire_token request is served by broker, the RT will not be available from the return value. So, if your MSAL-Python-powered app or sdk used to rely on RT to work, you would need to redesign your app/sdk accordingly.

Roadmap

The following features are not yet supported, but they are expected to be available in the near future. But you should not wait. Please start testing your app with this PR asap, and report back your findings or concerns.

  • Logging will include broker's debug logs Done
  • Provide support for max_age in broker code path Done.
  • Other adjustments in select_account and remove_account() behavior. But their MSAL Python API are expected to remain unchanged. Done.

P.S.:

CC: @jiasli , @xiangyan99

msal/wam.py Outdated Show resolved Hide resolved
msal/wam.py Outdated Show resolved Hide resolved
msal/wam.py Outdated Show resolved Hide resolved
msal/wam.py Outdated Show resolved Hide resolved
msal/wam.py Outdated Show resolved Hide resolved
msal/wam.py Outdated Show resolved Hide resolved
msal/wam.py Outdated Show resolved Hide resolved
@rayluo rayluo changed the title WAM/Mid-tier integration Broker integration Feb 16, 2022
@rayluo rayluo marked this pull request as ready for review February 16, 2022 08:40
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
msal/broker.py Outdated Show resolved Hide resolved
setup.cfg Outdated Show resolved Hide resolved
setup.py Outdated Show resolved Hide resolved
setup.py Outdated Show resolved Hide resolved
@rayluo rayluo force-pushed the wam branch 3 times, most recently from 77b72a6 to a457b72 Compare April 20, 2022 23:38
msal/application.py Outdated Show resolved Hide resolved
msal/application.py Outdated Show resolved Hide resolved
# OTOH, AAD would emit other errors when other error handling branch was hit first,
# so, the AADSTS50011/RedirectUriError is not guaranteed to happen.
return {
"error": "broker_error", # Note: Broker implies your device needs to be compliant.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If getting a certificate fails in Cloud Shell, MSAL also raises broker_error.

if oauth2_response["token_type"] != expected_token_type:
return { # Generate a normal error (rather than an intrusive exception)
"error": "broker_error",
"error_description": "token_type {} is not supported by this version of Azure Portal".format(
expected_token_type),
}

Certainly this "broker" (WAM) is different from Cloud Shell's broker (pseudo managed identity). Expected?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the two feature were developed side-by-side in the same period. So, the naming of "broker" is deliberate. In both scenarios, MSAL Python does not obtain token directly from the original source AAD, but utilize a mechanism available in the current environment to get a token from a "middle man". We consider that "man" a broker. :-) In the future, we expect other brokers available on Linux and macOS, too.

Disabled SSH Cert when using broker
Apply the refactor to similar code path
@rayluo rayluo merged commit 97af2b3 into dev Oct 7, 2022
@rayluo rayluo deleted the wam branch October 7, 2022 04:30
@rayluo rayluo mentioned this pull request Oct 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add WAM Support to MSAL for Python, for cross-language consistency
5 participants