From 4fad74275117db5c96e6a08d8065e8f527f9cbd5 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:12:39 +0100 Subject: [PATCH 01/18] adding articles from identity platform, modified TOC --- msal-python-conceptual/TOC.yml | 10 +- .../advanced/migrate-python-adal-msal.md | 107 ++++++++++++++++++ .../advanced/msal-error-handling-python.md | 77 +++++++++++++ .../advanced/msal-logging-python.md | 65 +++++++++++ .../advanced/msal-python-adfs-support.md | 54 +++++++++ .../msal-python-token-cache-serialization.md | 24 ++++ 6 files changed, 332 insertions(+), 5 deletions(-) create mode 100644 msal-python-conceptual/advanced/migrate-python-adal-msal.md create mode 100644 msal-python-conceptual/advanced/msal-error-handling-python.md create mode 100644 msal-python-conceptual/advanced/msal-logging-python.md create mode 100644 msal-python-conceptual/advanced/msal-python-adfs-support.md create mode 100644 msal-python-conceptual/advanced/msal-python-token-cache-serialization.md diff --git a/msal-python-conceptual/TOC.yml b/msal-python-conceptual/TOC.yml index 35dd4c2..96edb07 100644 --- a/msal-python-conceptual/TOC.yml +++ b/msal-python-conceptual/TOC.yml @@ -13,19 +13,19 @@ - name: Using MSAL Python with Web Account Manager href: advanced/wam.md - name: Migrate to MSAL Python - href: /azure/active-directory/develop/migrate-python-adal-msal + href: migrate-python-adal-msal.md - name: Logging - href: /azure/active-directory/develop/msal-logging-python + href: msal-logging-python.md - name: Handle errors and exceptions - href: /azure/active-directory/develop/msal-error-handling-python + href: msal-error-handling-python.md - name: Conditional access href: advanced/conditional-access.md - name: Token cache serialization - href: /azure/active-directory/develop/msal-python-token-cache-serialization + href: msal-python-token-cache-serialization.md - name: Developing an Azure AD B2C app with MSAL Python href: advanced/aad-b2c.md - name: Active Directory Federation Services (ADFS) Support - href: /azure/active-directory/develop/msal-python-adfs-support + href: msal-python-adfs-support.md - name: National clouds href: /azure/active-directory/develop/msal-national-cloud?tabs=python - name: Username and password authentication diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md new file mode 100644 index 0000000..26c395f --- /dev/null +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -0,0 +1,107 @@ +--- +title: Python ADAL to MSAL migration guide +description: Learn how to migrate your Azure Active Directory Authentication Library (ADAL) Python app to the Microsoft Authentication Library (MSAL) for Python. +--- + +# ADAL to MSAL migration guide for Python + +This article highlights changes you need to make to migrate an app that uses the Azure Active Directory Authentication Library (ADAL) to use the Microsoft Authentication Library (MSAL). + +You can learn more about MSAL and get started with an [overview of the Microsoft Authentication Library](msal-overview.md). + +## Difference highlights + +ADAL works with the Azure Active Directory (Azure AD) v1.0 endpoint. The Microsoft Authentication Library (MSAL) works with the Microsoft identity platform--formerly known as the Azure Active Directory v2.0 endpoint. The Microsoft identity platform differs from Azure AD v1.0 in that it: + +Supports: + +- Work and school accounts (Azure AD provisioned accounts) +- Personal accounts (such as Outlook.com or Hotmail.com) +- Your customers who bring their own email or social identity (such as LinkedIn, Facebook, Google) via the Azure AD B2C offering + +- Is standards compatible with: + - OAuth v2.0 + - OpenID Connect (OIDC) + +For more information about MSAL, see [MSAL overview](./msal-overview.md). + +### Scopes not resources + +ADAL Python acquires tokens for resources, but MSAL Python acquires tokens for scopes. The API surface in MSAL Python doesn't have resource parameter anymore. You would need to provide scopes as a list of strings that declare the desired permissions and resources that are requested. To see some example of scopes, see [Microsoft Graph's scopes](/graph/permissions-reference). + +You can add the `/.default` scope suffix to the resource to help migrate your apps from the v1.0 endpoint (ADAL) to the Microsoft identity platform (MSAL). For example, for the resource value of `https://graph.microsoft.com`, the equivalent scope value is `https://graph.microsoft.com/.default`. If the resource isn't in the URL form, but a resource ID of the form `XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX`, you can still use the scope value as `XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/.default`. + +For more details about the different types of scopes, refer to [Permissions and consent in the Microsoft identity platform](/azure/active-directory/develop/permissions-consent-overview.md) and the [Scopes for a Web API accepting v1.0 tokens](/azure/active-directory/develop/msal-v1-app-scopes.md) articles. + +### Error handling + +ADAL for Python uses the exception `AdalError` to indicate that there's been a problem. MSAL for Python typically uses error codes, instead. For more information, see [MSAL for Python error handling](msal-error-handling-python.md). + +### API changes + +The following table lists an API in ADAL for Python, and the one to use in its place in MSAL for Python: + +| ADAL for Python API | MSAL for Python API | +| ------------------- | ------------------- | +| [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.__init__) or [ConfidentialClientApplication](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.__init__) | +| N/A | [PublicClientApplication.acquire_token_interactive()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_interactive) | +| N/A | [ConfidentialClientApplication.initiate_auth_code_flow()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.initiate_auth_code_flow) | +| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ConfidentialClientApplication.acquire_token_by_auth_code_flow()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_by_auth_code_flow) | +| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [PublicClientApplication.acquire_token_silent()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_silent) or [ConfidentialClientApplication.acquire_token_silent()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_silent) | +| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [PublicClientApplication.acquire_token_by_refresh_token()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_refresh_token) or [ConfidentialClientApplication.acquire_token_by_refresh_token()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_by_refresh_token) | +| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | [initiate_device_flow()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.initiate_device_flow) | +| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | [acquire_token_by_device_flow()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_device_flow) | +| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | [acquire_token_by_username_password()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_username_password) | +| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | [acquire_token_for_client()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_for_client) | +| N/A | [acquire_token_on_behalf_of()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_on_behalf_of) | +| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | [SerializableTokenCache()](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache) | +| N/A | Cache with persistence, available from [MSAL Extensions](https://github.com/marstr/original-microsoft-authentication-extensions-for-python) | + +## Migrate existing refresh tokens for MSAL Python + +MSAL abstracts the concept of refresh tokens. MSAL Python provides an in-memory token cache by default so that you don't need to store, lookup, or update refresh tokens. Users will also see fewer sign-in prompts because refresh tokens can usually be updated without user intervention. For more information about the token cache, see [Custom token cache serialization in MSAL for Python](msal-python-token-cache-serialization.md). + +The following code will help you migrate your refresh tokens managed by another OAuth2 library (including but not limited to ADAL Python) to be managed by MSAL for Python. One reason for migrating those refresh tokens is to prevent existing users from needing to sign in again when you migrate your app to MSAL for Python. + +The method for migrating a refresh token is to use MSAL for Python to acquire a new access token using the previous refresh token. When the new refresh token is returned, MSAL for Python will store it in the cache. +Since MSAL Python 1.3.0, we provide an API inside MSAL for this purpose. +Please refer to the following code snippet, quoted from +[a completed sample of migrating refresh tokens with MSAL Python](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.3.0/sample/migrate_rt.py#L28-L67) + +```python +import msal +def get_preexisting_rt_and_their_scopes_from_elsewhere(): + # Maybe you have an ADAL-powered app like this + # https://github.com/AzureAD/azure-activedirectory-library-for-python/blob/1.2.3/sample/device_code_sample.py#L72 + # which uses a resource rather than a scope, + # you need to convert your v1 resource into v2 scopes + # See https://learn.microsoft.com/azure/active-directory/develop/migrate-python-adal-msal#scopes-not-resources + # You may be able to append "/.default" to your v1 resource to form a scope + # See https://learn.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope + + # Or maybe you have an app already talking to the Microsoft identity platform, + # powered by some 3rd-party auth library, and persist its tokens somehow. + + # Either way, you need to extract RTs from there, and return them like this. + return [ + ("old_rt_1", ["scope1", "scope2"]), + ("old_rt_2", ["scope3", "scope4"]), + ] + + +# We will migrate all the old RTs into a new app powered by MSAL +app = msal.PublicClientApplication( + "client_id", authority="...", + # token_cache=... # Default cache is in memory only. + # You can learn how to use SerializableTokenCache from + # https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache + ) + +# We choose a migration strategy of migrating all RTs in one loop +for old_rt, scopes in get_preexisting_rt_and_their_scopes_from_elsewhere(): + result = app.acquire_token_by_refresh_token(old_rt, scopes) + if "error" in result: + print("Discarding unsuccessful RT. Error: ", json.dumps(result, indent=2)) + +print("Migration completed") +``` \ No newline at end of file diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md new file mode 100644 index 0000000..1ea502a --- /dev/null +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -0,0 +1,77 @@ +--- +title: Handle errors and exceptions in MSAL for Python +description: Learn how to handle errors and exceptions, Conditional Access claims challenges, and retries in MSAL for Python applications. +--- +# Handle errors and exceptions in MSAL for Python + +[!INCLUDE [Active directory error handling introduction](/azure/active-directory/develop/includes/error-handling-and-tips/error-handling-introduction.md)] + +## Error handling in MSAL for Python + +In MSAL for Python, most errors are conveyed as a return value from the API call. The error is represented as a dictionary containing the JSON response from the Microsoft identity platform. + +* A successful response contains the `"access_token"` key. The format of the response is defined by the OAuth2 protocol. For more information, see [5.1 Successful Response](https://tools.ietf.org/html/rfc6749#section-5.1) +* An error response contains `"error"` and usually `"error_description"`. The format of the response is defined by the OAuth2 protocol. For more information, see [5.2 Error Response](https://tools.ietf.org/html/rfc6749#section-5.2) + +When an error is returned, the `"error"` key contains a machine-readable code. If the `"error"` is, for example, an `"interaction_required"`, you may prompt the user to provide additional information to complete the authentication process. If the `"error"` is `"invalid_grant"`, you may prompt the user to reenter their credentials. The following snippet is an example of error handling in MSAL for Python. + +```python + +from msal import ConfidentialClientApplication + +authority_url = "https://login.microsoftonline.com/your_tenant_id" +client_id = "your_client_id" +client_secret = "your_client_secret" +scopes = ["https://graph.microsoft.com/.default"] + +app = ConfidentialClientApplication(client_id, authority=authority_url, client_credential=client_secret) + +result = app.acquire_token_silent(scopes=scopes, account=None) + +if not result: + result = app.acquire_token_silent(scopes=scopes) + +if "access_token" in result: + print("Access token: %s" % result["access_token"]) +else: + print("Error: %s" % result.get("error")) + +``` + +When an error is returned, the `"error_description"` key also contains a human-readable message, and there is typically also an `"error_code"` key which contains a machine-readable Microsoft identity platform error code. For more information about the various Microsoft identity platform error codes, see [Authentication and authorization error codes](/azure/active-directory/develop/reference-error-codes.md). + +In MSAL for Python, exceptions are rare because most errors are handled by returning an error value. The `ValueError` exception is only thrown when there's an issue with how you're attempting to use the library, such as when API parameter(s) are malformed. + +[!INCLUDE [Active directory error handling claims challenges](/azure/active-directory/develop/includes/error-handling-and-tips/error-handling-claims-challenges.md)] + + +## Retrying after errors and exceptions + +MSAL makes HTTP calls to the Azure AD service, and occasionally failures can occur. +For example the network can go down or the server is overloaded. + +MSAL Python 1.11+ automatically performs one retry attempt for you. +You may customize this behavior by following +[this instruction](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.params.http_client). + +### HTTP 429 + +When the Service Token Server (STS) is overloaded with too many requests, +it returns HTTP error 429 with a hint about how long until you can try again in the `Retry-After` response field. + +Your app was expected to throttle the subsequent requests, and only retry after the specified period. +That was not an easy task. + +MSAL Python 1.16+ made it easy for you, in that your app could blindly retry in any given time +(say, whenever the end user clicks the sign-in button again), +MSAL Python 1.16+ would automatically throttle those retry attempts by returning same error response from an HTTP cache, +and only sending out a real HTTP call when that call is attempted after the specified period. + +By default, this throttle mechanism works by saving throttle information into a built-in in-memory HTTP cache. +You may provide your own `dict`-like object as the HTTP cache, which you can control how to persist its content. +See [MSAL Python's API document](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.params.http_cache) +for more details. + +## Next steps + +Consider enabling [Logging in MSAL for Python](msal-logging-python.md) to help you diagnose and debug issues. \ No newline at end of file diff --git a/msal-python-conceptual/advanced/msal-logging-python.md b/msal-python-conceptual/advanced/msal-logging-python.md new file mode 100644 index 0000000..54d8d70 --- /dev/null +++ b/msal-python-conceptual/advanced/msal-logging-python.md @@ -0,0 +1,65 @@ +--- +title: Logging errors and exceptions in MSAL for Python +description: Learn how to log errors and exceptions in MSAL for Python +--- + +# Logging in MSAL for Python + +[!INCLUDE [MSAL logging introduction](/azure/active-directory/develop/includes/error-handling-and-tips/error-logging-introduction.md)] + +## MSAL for Python logging + +Logging in MSAL for Python leverages the [logging module in the Python standard library](https://docs.python.org/3/library/logging.html). You can configure MSAL logging as follows (and see it in action in the [username_password_sample](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.0.0/sample/username_password_sample.py#L31L32)): + +### Enable debug logging for all modules + +By default, the logging in any Python script is turned off. If you want to enable verbose logging for **all** Python modules in your script, use `logging.basicConfig` with a level of `logging.DEBUG`: + +```python +import logging + +logging.basicConfig(level=logging.DEBUG) +``` + +This will print all log messages given to the logging module to the standard output. + +### Configure MSAL logging level + +You can configure the logging level of the MSAL for Python log provider by using the `logging.getLogger()` method with the logger name `"msal"`: + +```python +import logging + +logging.getLogger("msal").setLevel(logging.WARN) +``` + +### Configure MSAL logging with Azure App Insights + +Python logs are given to a log handler, which by default is the `StreamHandler`. To send MSAL logs to an Application Insights with an Instrumentation Key, use the `AzureLogHandler` provided by the `opencensus-ext-azure` library. + +To install, `opencensus-ext-azure` add the `opencensus-ext-azure` package from PyPI to your dependencies or pip install: + +```console +pip install opencensus-ext-azure +``` + +Then change the default handler of the `"msal"` log provider to an instance of `AzureLogHandler` with an instrumentation key set in the `APP_INSIGHTS_KEY` environment variable: + +```python +import logging +import os + +from opencensus.ext.azure.log_exporter import AzureLogHandler + +APP_INSIGHTS_KEY = os.getenv('APP_INSIGHTS_KEY') + +logging.getLogger("msal").addHandler(AzureLogHandler(connection_string='InstrumentationKey={0}'.format(APP_INSIGHTS_KEY))) +``` + +### Personal and organizational data in Python + +MSAL for Python does not log personal data or organizational data. There is no property to turn personal or organization data logging on or off. + +You can use standard Python logging to log whatever you want, but you are responsible for safely handling sensitive data and following regulatory requirements. + +For more information about logging in Python, please refer to Python's [Logging: how-to](https://docs.python.org/3/howto/logging.html#logging-basic-tutorial). \ No newline at end of file diff --git a/msal-python-conceptual/advanced/msal-python-adfs-support.md b/msal-python-conceptual/advanced/msal-python-adfs-support.md new file mode 100644 index 0000000..6e04340 --- /dev/null +++ b/msal-python-conceptual/advanced/msal-python-adfs-support.md @@ -0,0 +1,54 @@ +--- +title: Azure AD FS support (MSAL Python) +description: Learn about Active Directory Federation Services (AD FS) support in the Microsoft Authentication Library for Python +services: active-directory +author: Dickson-Mwendia +manager: CelesteDG + +ms.service: active-directory +ms.subservice: develop +ms.topic: conceptual +ms.workload: identity +ms.date: 11/23/2019 +ms.author: dmwendia +ms.reviewer: celested, nacanuma +ms.custom: aaddev, devx-track-python, has-adal-ref +#Customer intent: As an application developer, I want to learn about AD FS support in MSAL for Python so I can decide if this platform meets my application development needs and requirements. +--- + +# Active Directory Federation Services support in MSAL for Python + +Active Directory Federation Services (AD FS) in Windows Server enables you to add OpenID Connect and OAuth 2.0 based authentication and authorization to your apps by using the Microsoft Authentication Library (MSAL) for Python. Using the MSAL for Python library, your app can authenticate users directly against AD FS. For more information about scenarios, see [AD FS Scenarios for Developers](/windows-server/identity/ad-fs/ad-fs-development). + +There are usually two ways of authenticating against AD FS: + +- MSAL Python talks to Azure Active Directory, which itself is federated with other identity providers. The federation happens through AD FS. MSAL Python connects to Azure AD, which signs in users that are managed in Azure AD (managed users) or users managed by another identity provider such as AD FS (federated users). MSAL Python doesn't know that a user is federated. It simply talks to Azure AD. The [authority](msal-client-application-configuration.md#authority) you use in this case is the usual authority (authority host name + tenant, common, or organizations). +- MSAL Python talks directly to an AD FS authority. This is only supported by AD FS 2019 and later. + +## Connect to Active Directory federated with AD FS + +### Acquire a token interactively for a federated user + +The following applies whether you connect directly to Active Directory Federation Services (AD FS) or through Active Directory. + +When you call `acquire_token_by_authorization_code` or `acquire_token_by_device_flow`, the user experience is typically as follows: + +1. The user enters their account ID. +2. Azure AD displays briefly the message "Taking you to your organization's page" and the user is redirected to the sign-in page of the identity provider. The sign-in page is usually customized with the logo of the organization. + +The supported AD FS versions in this federated scenario are: +- Active Directory Federation Services FS v2 +- Active Directory Federation Services v3 (Windows Server 2012 R2) +- Active Directory Federation Services v4 (AD FS 2016) + +### Acquire a token via username and password + +The following applies whether you connect directly to Active Directory Federation Services (AD FS) or through Active Directory. + +When you acquire a token using `acquire_token_by_username_password`, MSAL Python gets the identity provider to contact based on the username. MSAL Python gets a [SAML 1.1 token](reference-saml-tokens.md) from the identity provider, which it then provides to Azure AD which returns the JSON Web Token (JWT). + +## Connecting directly to AD FS + +When you connect directory to AD FS, the authority you'll want to use to build your application will be something like `https://somesite.contoso.com/adfs/` + +MSAL Python supports ADFS 2019, but does not support a direct connection to ADFS 2016 or ADFS v2. Once you have upgraded your on-premises system to ADFS 2019, you can use MSAL Python. \ No newline at end of file diff --git a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md new file mode 100644 index 0000000..f8752d3 --- /dev/null +++ b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md @@ -0,0 +1,24 @@ +--- +title: Custom token cache serialization (MSAL Python) +description: Learn how to serialize token cache using MSAL for Python +--- + +# Custom token cache serialization in MSAL for Python + +In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of [ClientApplication](/python/api/msal/msal.application.confidentialclientapplication). + +Serialization of the token cache, so that different sessions of your app can access it, isn't provided "out of the box." MSAL for Python can be used in app types that don't have access to the file system--such as Web apps. To have a persistent token cache in an app that uses MSAL for Python, you must provide custom token cache serialization. + +The strategies for serializing the token cache differ depending on whether you're writing a public client application (Desktop), or a confidential client application (web app, web API, or daemon app). + +## Token cache for a public client application + +Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the [SerializableTokenCache](/python/api/msal/msal.token_cache.serializabletokencache) class reference documentation. + +## Token cache for a Web app (confidential client application) + +For web apps or web APIs, you might use the session, or a Redis cache, or a database to store the token cache. There should be one token cache per user (per account) so ensure that you serialize the token cache per account. + +## Next steps + +See [ms-identity-python-webapp](https://github.com/Azure-Samples/ms-identity-python-webapp/blob/0.3.0/app.py#L66-L74) for an example of how to use the token cache for a Windows or Linux Web app or web API. The example is for a web app that calls the Microsoft Graph API. \ No newline at end of file From 038e1ff96fb9203611788a72d8a134bd6a67e019 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:27:02 +0100 Subject: [PATCH 02/18] addressing build errors --- msal-python-conceptual/TOC.yml | 10 +++---- .../advanced/migrate-python-adal-msal.md | 6 ++--- .../advanced/msal-error-handling-python.md | 26 ++++++++++++++++--- .../advanced/msal-logging-python.md | 22 +++++++++++++++- .../advanced/msal-python-adfs-support.md | 13 ---------- 5 files changed, 52 insertions(+), 25 deletions(-) diff --git a/msal-python-conceptual/TOC.yml b/msal-python-conceptual/TOC.yml index 96edb07..d11ba37 100644 --- a/msal-python-conceptual/TOC.yml +++ b/msal-python-conceptual/TOC.yml @@ -13,19 +13,19 @@ - name: Using MSAL Python with Web Account Manager href: advanced/wam.md - name: Migrate to MSAL Python - href: migrate-python-adal-msal.md + href: advanced/migrate-python-adal-msal.md - name: Logging - href: msal-logging-python.md + href: advanced/msal-logging-python.md - name: Handle errors and exceptions - href: msal-error-handling-python.md + href: advanced/msal-error-handling-python.md - name: Conditional access href: advanced/conditional-access.md - name: Token cache serialization - href: msal-python-token-cache-serialization.md + href: advanced/msal-python-token-cache-serialization.md - name: Developing an Azure AD B2C app with MSAL Python href: advanced/aad-b2c.md - name: Active Directory Federation Services (ADFS) Support - href: msal-python-adfs-support.md + href: advanced/msal-python-adfs-support.md - name: National clouds href: /azure/active-directory/develop/msal-national-cloud?tabs=python - name: Username and password authentication diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index 26c395f..e924aba 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -7,7 +7,7 @@ description: Learn how to migrate your Azure Active Directory Authentication Lib This article highlights changes you need to make to migrate an app that uses the Azure Active Directory Authentication Library (ADAL) to use the Microsoft Authentication Library (MSAL). -You can learn more about MSAL and get started with an [overview of the Microsoft Authentication Library](msal-overview.md). +You can learn more about MSAL and get started with an [overview of the Microsoft Authentication Library for Python](../index.md). ## Difference highlights @@ -23,7 +23,7 @@ Supports: - OAuth v2.0 - OpenID Connect (OIDC) -For more information about MSAL, see [MSAL overview](./msal-overview.md). +For more information about MSAL, see [MSAL overview](../index.md). ### Scopes not resources @@ -31,7 +31,7 @@ ADAL Python acquires tokens for resources, but MSAL Python acquires tokens for s You can add the `/.default` scope suffix to the resource to help migrate your apps from the v1.0 endpoint (ADAL) to the Microsoft identity platform (MSAL). For example, for the resource value of `https://graph.microsoft.com`, the equivalent scope value is `https://graph.microsoft.com/.default`. If the resource isn't in the URL form, but a resource ID of the form `XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX`, you can still use the scope value as `XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/.default`. -For more details about the different types of scopes, refer to [Permissions and consent in the Microsoft identity platform](/azure/active-directory/develop/permissions-consent-overview.md) and the [Scopes for a Web API accepting v1.0 tokens](/azure/active-directory/develop/msal-v1-app-scopes.md) articles. +For more details about the different types of scopes, refer to [Permissions and consent in the Microsoft identity platform](/azure/active-directory/develop/permissions-consent-overview) and the [Scopes for a Web API accepting v1.0 tokens](/azure/active-directory/develop/msal-v1-app-scopes) articles. ### Error handling diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md index 1ea502a..114d4e1 100644 --- a/msal-python-conceptual/advanced/msal-error-handling-python.md +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -4,7 +4,27 @@ description: Learn how to handle errors and exceptions, Conditional Access claim --- # Handle errors and exceptions in MSAL for Python -[!INCLUDE [Active directory error handling introduction](/azure/active-directory/develop/includes/error-handling-and-tips/error-handling-introduction.md)] +The Microsoft Authentication Library (MSAL) apps generate log messages that can help diagnose issues. An app can configure logging with a few lines of code, and have custom control over the level of detail and whether or not personal and organizational data is logged. We recommend you create an MSAL logging implementation and provide a way for users to submit logs when they have authentication issues. + +## Logging levels + +MSAL provides several levels of logging detail: + +- LogAlways: No level filtering is done on this log level. Log messages of all levels will be logged. +- Critical: Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention. +- Error: Indicates something has gone wrong and an error was generated. Used for debugging and identifying problems. +- Warning: There hasn't necessarily been an error or failure, but are intended for diagnostics and pinpointing problems. +- Informational: MSAL will log events intended for informational purposes not necessarily intended for debugging. +- Verbose (Default): MSAL logs the full details of library behavior. + +> [!NOTE] +> Not all log levels are available for all MSAL SDK's + +## Personal and organizational data + +By default, the MSAL logger doesn't capture any highly sensitive personal or organizational data. The library provides the option to enable logging personal and organizational data if you decide to do so. + +The following sections provide more details about MSAL error logging for your application. ## Error handling in MSAL for Python @@ -38,11 +58,11 @@ else: ``` -When an error is returned, the `"error_description"` key also contains a human-readable message, and there is typically also an `"error_code"` key which contains a machine-readable Microsoft identity platform error code. For more information about the various Microsoft identity platform error codes, see [Authentication and authorization error codes](/azure/active-directory/develop/reference-error-codes.md). +When an error is returned, the `"error_description"` key also contains a human-readable message, and there is typically also an `"error_code"` key which contains a machine-readable Microsoft identity platform error code. For more information about the various Microsoft identity platform error codes, see [Authentication and authorization error codes](/azure/active-directory/develop/reference-error-codes). In MSAL for Python, exceptions are rare because most errors are handled by returning an error value. The `ValueError` exception is only thrown when there's an issue with how you're attempting to use the library, such as when API parameter(s) are malformed. -[!INCLUDE [Active directory error handling claims challenges](/azure/active-directory/develop/includes/error-handling-and-tips/error-handling-claims-challenges.md)] +[!INCLUDE [Active directory error handling claims challenges](/azure/active-directory/develop/includes/error-handling-and-tips/error-handling-claims-challenges)] ## Retrying after errors and exceptions diff --git a/msal-python-conceptual/advanced/msal-logging-python.md b/msal-python-conceptual/advanced/msal-logging-python.md index 54d8d70..0cc5200 100644 --- a/msal-python-conceptual/advanced/msal-logging-python.md +++ b/msal-python-conceptual/advanced/msal-logging-python.md @@ -5,7 +5,27 @@ description: Learn how to log errors and exceptions in MSAL for Python # Logging in MSAL for Python -[!INCLUDE [MSAL logging introduction](/azure/active-directory/develop/includes/error-handling-and-tips/error-logging-introduction.md)] +The Microsoft Authentication Library (MSAL) apps generate log messages that can help diagnose issues. An app can configure logging with a few lines of code, and have custom control over the level of detail and whether or not personal and organizational data is logged. We recommend you create an MSAL logging implementation and provide a way for users to submit logs when they have authentication issues. + +## Logging levels + +MSAL provides several levels of logging detail: + +- LogAlways: No level filtering is done on this log level. Log messages of all levels will be logged. +- Critical: Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention. +- Error: Indicates something has gone wrong and an error was generated. Used for debugging and identifying problems. +- Warning: There hasn't necessarily been an error or failure, but are intended for diagnostics and pinpointing problems. +- Informational: MSAL will log events intended for informational purposes not necessarily intended for debugging. +- Verbose (Default): MSAL logs the full details of library behavior. + +> [!NOTE] +> Not all log levels are available for all MSAL SDK's + +## Personal and organizational data + +By default, the MSAL logger doesn't capture any highly sensitive personal or organizational data. The library provides the option to enable logging personal and organizational data if you decide to do so. + +The following sections provide more details about MSAL error logging for your application. ## MSAL for Python logging diff --git a/msal-python-conceptual/advanced/msal-python-adfs-support.md b/msal-python-conceptual/advanced/msal-python-adfs-support.md index 6e04340..e11e62f 100644 --- a/msal-python-conceptual/advanced/msal-python-adfs-support.md +++ b/msal-python-conceptual/advanced/msal-python-adfs-support.md @@ -1,19 +1,6 @@ --- title: Azure AD FS support (MSAL Python) description: Learn about Active Directory Federation Services (AD FS) support in the Microsoft Authentication Library for Python -services: active-directory -author: Dickson-Mwendia -manager: CelesteDG - -ms.service: active-directory -ms.subservice: develop -ms.topic: conceptual -ms.workload: identity -ms.date: 11/23/2019 -ms.author: dmwendia -ms.reviewer: celested, nacanuma -ms.custom: aaddev, devx-track-python, has-adal-ref -#Customer intent: As an application developer, I want to learn about AD FS support in MSAL for Python so I can decide if this platform meets my application development needs and requirements. --- # Active Directory Federation Services support in MSAL for Python From 48ca42ef3a91b26f0893b6e610299f2869936b3c Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:34:59 +0100 Subject: [PATCH 03/18] addressing build errors #2 --- .../advanced/msal-error-handling-python.md | 8 +++++++- .../advanced/msal-python-adfs-support.md | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md index 114d4e1..b7042c1 100644 --- a/msal-python-conceptual/advanced/msal-error-handling-python.md +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -62,7 +62,13 @@ When an error is returned, the `"error_description"` key also contains a human-r In MSAL for Python, exceptions are rare because most errors are handled by returning an error value. The `ValueError` exception is only thrown when there's an issue with how you're attempting to use the library, such as when API parameter(s) are malformed. -[!INCLUDE [Active directory error handling claims challenges](/azure/active-directory/develop/includes/error-handling-and-tips/error-handling-claims-challenges)] +## Conditional Access and claims challenges + +When getting tokens silently, your application may receive errors when a [Conditional Access claims challenge](../../v2-conditional-access-dev-guide.md) such as MFA policy is required by an API you're trying to access. + +The pattern for handling this error is to interactively acquire a token using MSAL. This prompts the user and gives them the opportunity to satisfy the required Conditional Access policy. + +In certain cases when calling an API requiring Conditional Access, you can receive a claims challenge in the error from the API. For instance if the Conditional Access policy is to have a managed device (Intune) the error will be something like [AADSTS53000: Your device is required to be managed to access this resource](/azure/active-directory/develop/reference-error-codes) or something similar. In this case, you can pass the claims in the acquire token call so that the user is prompted to satisfy the appropriate policy. ## Retrying after errors and exceptions diff --git a/msal-python-conceptual/advanced/msal-python-adfs-support.md b/msal-python-conceptual/advanced/msal-python-adfs-support.md index e11e62f..dba5754 100644 --- a/msal-python-conceptual/advanced/msal-python-adfs-support.md +++ b/msal-python-conceptual/advanced/msal-python-adfs-support.md @@ -9,7 +9,7 @@ Active Directory Federation Services (AD FS) in Windows Server enables you to ad There are usually two ways of authenticating against AD FS: -- MSAL Python talks to Azure Active Directory, which itself is federated with other identity providers. The federation happens through AD FS. MSAL Python connects to Azure AD, which signs in users that are managed in Azure AD (managed users) or users managed by another identity provider such as AD FS (federated users). MSAL Python doesn't know that a user is federated. It simply talks to Azure AD. The [authority](msal-client-application-configuration.md#authority) you use in this case is the usual authority (authority host name + tenant, common, or organizations). +- MSAL Python talks to Azure Active Directory, which itself is federated with other identity providers. The federation happens through AD FS. MSAL Python connects to Azure AD, which signs in users that are managed in Azure AD (managed users) or users managed by another identity provider such as AD FS (federated users). MSAL Python doesn't know that a user is federated. It simply talks to Azure AD. The [authority](/azure/active-directory/develop/msal-client-application-configuration#authority) you use in this case is the usual authority (authority host name + tenant, common, or organizations). - MSAL Python talks directly to an AD FS authority. This is only supported by AD FS 2019 and later. ## Connect to Active Directory federated with AD FS @@ -32,7 +32,7 @@ The supported AD FS versions in this federated scenario are: The following applies whether you connect directly to Active Directory Federation Services (AD FS) or through Active Directory. -When you acquire a token using `acquire_token_by_username_password`, MSAL Python gets the identity provider to contact based on the username. MSAL Python gets a [SAML 1.1 token](reference-saml-tokens.md) from the identity provider, which it then provides to Azure AD which returns the JSON Web Token (JWT). +When you acquire a token using `acquire_token_by_username_password`, MSAL Python gets the identity provider to contact based on the username. MSAL Python gets a [SAML 1.1 token](/azure/active-directory/develop/reference-saml-tokens.md) from the identity provider, which it then provides to Azure AD which returns the JSON Web Token (JWT). ## Connecting directly to AD FS From 29ee3976f2973f4c9a687980cf8b2b2acc23cf91 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:37:44 +0100 Subject: [PATCH 04/18] addressing build errors #3 --- msal-python-conceptual/advanced/msal-error-handling-python.md | 2 +- msal-python-conceptual/advanced/msal-python-adfs-support.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md index b7042c1..accd6bf 100644 --- a/msal-python-conceptual/advanced/msal-error-handling-python.md +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -64,7 +64,7 @@ In MSAL for Python, exceptions are rare because most errors are handled by retur ## Conditional Access and claims challenges -When getting tokens silently, your application may receive errors when a [Conditional Access claims challenge](../../v2-conditional-access-dev-guide.md) such as MFA policy is required by an API you're trying to access. +When getting tokens silently, your application may receive errors when a [Conditional Access claims challenge](/azure/active-directory/develop/v2-conditional-access-dev-guide) such as MFA policy is required by an API you're trying to access. The pattern for handling this error is to interactively acquire a token using MSAL. This prompts the user and gives them the opportunity to satisfy the required Conditional Access policy. diff --git a/msal-python-conceptual/advanced/msal-python-adfs-support.md b/msal-python-conceptual/advanced/msal-python-adfs-support.md index dba5754..87b7c58 100644 --- a/msal-python-conceptual/advanced/msal-python-adfs-support.md +++ b/msal-python-conceptual/advanced/msal-python-adfs-support.md @@ -32,7 +32,7 @@ The supported AD FS versions in this federated scenario are: The following applies whether you connect directly to Active Directory Federation Services (AD FS) or through Active Directory. -When you acquire a token using `acquire_token_by_username_password`, MSAL Python gets the identity provider to contact based on the username. MSAL Python gets a [SAML 1.1 token](/azure/active-directory/develop/reference-saml-tokens.md) from the identity provider, which it then provides to Azure AD which returns the JSON Web Token (JWT). +When you acquire a token using `acquire_token_by_username_password`, MSAL Python gets the identity provider to contact based on the username. MSAL Python gets a [SAML 1.1 token](/azure/active-directory/develop/reference-saml-tokens) from the identity provider, which it then provides to Azure AD which returns the JSON Web Token (JWT). ## Connecting directly to AD FS From caa545ed81012f118dcf024c37c2b8a38450fc65 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:25:55 +0100 Subject: [PATCH 05/18] msal references updated --- .../advanced/migrate-python-adal-msal.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index e924aba..c303dc6 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -43,18 +43,18 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ADAL for Python API | MSAL for Python API | | ------------------- | ------------------- | -| [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.__init__) or [ConfidentialClientApplication](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.__init__) | -| N/A | [PublicClientApplication.acquire_token_interactive()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_interactive) | -| N/A | [ConfidentialClientApplication.initiate_auth_code_flow()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.initiate_auth_code_flow) | -| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ConfidentialClientApplication.acquire_token_by_auth_code_flow()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_by_auth_code_flow) | -| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [PublicClientApplication.acquire_token_silent()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_silent) or [ConfidentialClientApplication.acquire_token_silent()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_silent) | -| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [PublicClientApplication.acquire_token_by_refresh_token()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_refresh_token) or [ConfidentialClientApplication.acquire_token_by_refresh_token()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_by_refresh_token) | -| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | [initiate_device_flow()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.initiate_device_flow) | -| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | [acquire_token_by_device_flow()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_device_flow) | -| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | [acquire_token_by_username_password()](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_username_password) | -| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | [acquire_token_for_client()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_for_client) | -| N/A | [acquire_token_on_behalf_of()](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.acquire_token_on_behalf_of) | -| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | [SerializableTokenCache()](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache) | +| [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](/python/api/msal/msal.application.publicclientapplication) or [ConfidentialClientApplication](/python/api/msal/msal.application.confidentialclientapplication) | +| N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication?view=msal-py-latest#msal-application-publicclientapplication-acquire-token-interactive) | +| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-initiate-auth-code-flow) | +| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-auth-code-flow) | +| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-silent) | +| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [ClientApplication.acquire_token_by_refresh_token()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-refresh-token) | +| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | [PublicClientApplication.initiate_device_flow()](/python/api/msal/msal.application.publicclientapplication?view=msal-py-latest#msal-application-publicclientapplication-initiate-device-flow) | +| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | [PublicClientApplication.acquire_token_by_device_flow()](/python/api/msal/msal.application.publicclientapplication?view=msal-py-latest#msal-application-publicclientapplication-acquire-token-by-device-flow) | +| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | [ClientApplication.acquire_token_by_username_password()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-username-password) | +| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | [ConfidentialClientApplication.acquire_token_for_client()](/python/api/msal/msal.application.confidentialclientapplication?view=msal-py-latest#msal-application-confidentialclientapplication-acquire-token-for-client) | +| N/A | [ConfidentialClientApplication.acquire_token_on_behalf_of()](/python/api/msal/msal.application.confidentialclientapplication?view=msal-py-latest#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) | +| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | [SerializableTokenCache()](/python/api/msal/msal.token_cache.serializabletokencache?view=msal-py-latest) | | N/A | Cache with persistence, available from [MSAL Extensions](https://github.com/marstr/original-microsoft-authentication-extensions-for-python) | ## Migrate existing refresh tokens for MSAL Python From 3ceced87486158c5f02764701d8798e35d58a6f3 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:29:53 +0100 Subject: [PATCH 06/18] testing no view link --- msal-python-conceptual/advanced/migrate-python-adal-msal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index c303dc6..07aea4f 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -44,7 +44,7 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ADAL for Python API | MSAL for Python API | | ------------------- | ------------------- | | [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](/python/api/msal/msal.application.publicclientapplication) or [ConfidentialClientApplication](/python/api/msal/msal.application.confidentialclientapplication) | -| N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication?view=msal-py-latest#msal-application-publicclientapplication-acquire-token-interactive) | +| N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-interactive) | | N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-initiate-auth-code-flow) | | [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-auth-code-flow) | | [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-silent) | From 879361dd97b7b7c46efa493e8fa80b5426eeef06 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:33:41 +0100 Subject: [PATCH 07/18] remove msal-view --- .../advanced/migrate-python-adal-msal.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index 07aea4f..42be336 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -45,16 +45,16 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ------------------- | ------------------- | | [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](/python/api/msal/msal.application.publicclientapplication) or [ConfidentialClientApplication](/python/api/msal/msal.application.confidentialclientapplication) | | N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-interactive) | -| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-initiate-auth-code-flow) | -| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-auth-code-flow) | -| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-silent) | -| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [ClientApplication.acquire_token_by_refresh_token()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-refresh-token) | -| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | [PublicClientApplication.initiate_device_flow()](/python/api/msal/msal.application.publicclientapplication?view=msal-py-latest#msal-application-publicclientapplication-initiate-device-flow) | -| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | [PublicClientApplication.acquire_token_by_device_flow()](/python/api/msal/msal.application.publicclientapplication?view=msal-py-latest#msal-application-publicclientapplication-acquire-token-by-device-flow) | -| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | [ClientApplication.acquire_token_by_username_password()](/python/api/msal/msal.application.clientapplication?view=msal-py-latest#msal-application-clientapplication-acquire-token-by-username-password) | -| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | [ConfidentialClientApplication.acquire_token_for_client()](/python/api/msal/msal.application.confidentialclientapplication?view=msal-py-latest#msal-application-confidentialclientapplication-acquire-token-for-client) | -| N/A | [ConfidentialClientApplication.acquire_token_on_behalf_of()](/python/api/msal/msal.application.confidentialclientapplication?view=msal-py-latest#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) | -| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | [SerializableTokenCache()](/python/api/msal/msal.token_cache.serializabletokencache?view=msal-py-latest) | +| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow) | +| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) | +| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) | +| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [ClientApplication.acquire_token_by_refresh_token()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-refresh-token) | +| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | [PublicClientApplication.initiate_device_flow()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-initiate-device-flow) | +| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | [PublicClientApplication.acquire_token_by_device_flow()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) | +| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | [ClientApplication.acquire_token_by_username_password()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-username-password) | +| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | [ConfidentialClientApplication.acquire_token_for_client()](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-for-client) | +| N/A | [ConfidentialClientApplication.acquire_token_on_behalf_of()](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) | +| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | [SerializableTokenCache()](/python/api/msal/msal.token_cache.serializabletokencache) | | N/A | Cache with persistence, available from [MSAL Extensions](https://github.com/marstr/original-microsoft-authentication-extensions-for-python) | ## Migrate existing refresh tokens for MSAL Python From b01802d6583236f90c1c7fdda359a902188b4c93 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Mon, 28 Aug 2023 10:02:21 +0100 Subject: [PATCH 08/18] langauge edit on README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e46efc0..680630e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Validate content links](https://github.com/MicrosoftDocs/microsoft-authentication-library-for-python/actions/workflows/linkchecker.yml/badge.svg)](https://github.com/MicrosoftDocs/microsoft-authentication-library-for-python/actions/workflows/linkchecker.yml) -This is the documentation repository for Microsoft Authentication Library (MSAL) for .NET. If you are looking for the library, refer to [AzureAD/microsoft-authentication-library-for-python](https://github.com/AzureAD/microsoft-authentication-library-for-python). +This is the documentation repository for Microsoft Authentication Library (MSAL) for Python. If you are looking for the library, refer to [AzureAD/microsoft-authentication-library-for-python](https://github.com/AzureAD/microsoft-authentication-library-for-python). ## Contributions From 6068cd07f270f024b8adf2150aaae0caa3c8d86d Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 09:31:40 +0100 Subject: [PATCH 09/18] updates following review, testing xref --- .../advanced/msal-error-handling-python.md | 36 ++++--------------- .../advanced/msal-logging-python.md | 14 ++++---- .../msal-python-token-cache-serialization.md | 4 +-- 3 files changed, 15 insertions(+), 39 deletions(-) diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md index accd6bf..f8e8e29 100644 --- a/msal-python-conceptual/advanced/msal-error-handling-python.md +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -2,31 +2,8 @@ title: Handle errors and exceptions in MSAL for Python description: Learn how to handle errors and exceptions, Conditional Access claims challenges, and retries in MSAL for Python applications. --- -# Handle errors and exceptions in MSAL for Python - -The Microsoft Authentication Library (MSAL) apps generate log messages that can help diagnose issues. An app can configure logging with a few lines of code, and have custom control over the level of detail and whether or not personal and organizational data is logged. We recommend you create an MSAL logging implementation and provide a way for users to submit logs when they have authentication issues. - -## Logging levels - -MSAL provides several levels of logging detail: - -- LogAlways: No level filtering is done on this log level. Log messages of all levels will be logged. -- Critical: Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention. -- Error: Indicates something has gone wrong and an error was generated. Used for debugging and identifying problems. -- Warning: There hasn't necessarily been an error or failure, but are intended for diagnostics and pinpointing problems. -- Informational: MSAL will log events intended for informational purposes not necessarily intended for debugging. -- Verbose (Default): MSAL logs the full details of library behavior. -> [!NOTE] -> Not all log levels are available for all MSAL SDK's - -## Personal and organizational data - -By default, the MSAL logger doesn't capture any highly sensitive personal or organizational data. The library provides the option to enable logging personal and organizational data if you decide to do so. - -The following sections provide more details about MSAL error logging for your application. - -## Error handling in MSAL for Python +# Handle errors and exceptions in MSAL for Python In MSAL for Python, most errors are conveyed as a return value from the API call. The error is represented as a dictionary containing the JSON response from the Microsoft identity platform. @@ -78,7 +55,7 @@ For example the network can go down or the server is overloaded. MSAL Python 1.11+ automatically performs one retry attempt for you. You may customize this behavior by following -[this instruction](https://msal-python.readthedocs.io/en/latest/#msal.ConfidentialClientApplication.params.http_client). +[the `http client` customization instruction](xref:msal.application.ConfidentialClientApplication). ### HTTP 429 @@ -86,18 +63,17 @@ When the Service Token Server (STS) is overloaded with too many requests, it returns HTTP error 429 with a hint about how long until you can try again in the `Retry-After` response field. Your app was expected to throttle the subsequent requests, and only retry after the specified period. -That was not an easy task. -MSAL Python 1.16+ made it easy for you, in that your app could blindly retry in any given time -(say, whenever the end user clicks the sign-in button again), +MSAL Python 1.16+ makes it easy for you to retry an authentication request on-demand +(for example, whenever the end-user clicks the sign-in button again), MSAL Python 1.16+ would automatically throttle those retry attempts by returning same error response from an HTTP cache, and only sending out a real HTTP call when that call is attempted after the specified period. By default, this throttle mechanism works by saving throttle information into a built-in in-memory HTTP cache. You may provide your own `dict`-like object as the HTTP cache, which you can control how to persist its content. -See [MSAL Python's API document](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.params.http_cache) +See [MSAL Python API documentation](xref:msal.application.PublicClientApplication) for more details. ## Next steps -Consider enabling [Logging in MSAL for Python](msal-logging-python.md) to help you diagnose and debug issues. \ No newline at end of file +- Consider enabling [Logging in MSAL for Python](msal-logging-python.md) to help you diagnose and debug issues. \ No newline at end of file diff --git a/msal-python-conceptual/advanced/msal-logging-python.md b/msal-python-conceptual/advanced/msal-logging-python.md index 0cc5200..04608a7 100644 --- a/msal-python-conceptual/advanced/msal-logging-python.md +++ b/msal-python-conceptual/advanced/msal-logging-python.md @@ -11,15 +11,15 @@ The Microsoft Authentication Library (MSAL) apps generate log messages that can MSAL provides several levels of logging detail: -- LogAlways: No level filtering is done on this log level. Log messages of all levels will be logged. -- Critical: Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention. -- Error: Indicates something has gone wrong and an error was generated. Used for debugging and identifying problems. -- Warning: There hasn't necessarily been an error or failure, but are intended for diagnostics and pinpointing problems. -- Informational: MSAL will log events intended for informational purposes not necessarily intended for debugging. -- Verbose (Default): MSAL logs the full details of library behavior. +- `LogAlways`: No level filtering is done on this log level. Log messages of all levels will be logged. +- `Critical`: Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention. +- `Error`: Indicates something has gone wrong and an error was generated. Used for debugging and identifying problems. +- `Warning`: There hasn't necessarily been an error or failure, but are intended for diagnostics and pinpointing problems. +- `Informational`: MSAL will log events intended for informational purposes not necessarily intended for debugging. +- `Verbose` (Default): MSAL logs the full details of library behavior. > [!NOTE] -> Not all log levels are available for all MSAL SDK's +> Not all log levels are available for all MSAL libraries. ## Personal and organizational data diff --git a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md index f8752d3..da95c3c 100644 --- a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md +++ b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md @@ -5,7 +5,7 @@ description: Learn how to serialize token cache using MSAL for Python # Custom token cache serialization in MSAL for Python -In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of [ClientApplication](/python/api/msal/msal.application.confidentialclientapplication). +In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of xref:msal.application.confidentialclientapplication. Serialization of the token cache, so that different sessions of your app can access it, isn't provided "out of the box." MSAL for Python can be used in app types that don't have access to the file system--such as Web apps. To have a persistent token cache in an app that uses MSAL for Python, you must provide custom token cache serialization. @@ -13,7 +13,7 @@ The strategies for serializing the token cache differ depending on whether you'r ## Token cache for a public client application -Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the [SerializableTokenCache](/python/api/msal/msal.token_cache.serializabletokencache) class reference documentation. +Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the xref:msal.token_cache.serializabletokencache class reference documentation. ## Token cache for a Web app (confidential client application) From 4c068fb875265e5cc809f18e6a28b30ed0e860c9 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 09:35:08 +0100 Subject: [PATCH 10/18] xref test 2 --- .../advanced/msal-python-token-cache-serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md index da95c3c..b2d44ec 100644 --- a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md +++ b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md @@ -5,7 +5,7 @@ description: Learn how to serialize token cache using MSAL for Python # Custom token cache serialization in MSAL for Python -In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of xref:msal.application.confidentialclientapplication. +In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of . Serialization of the token cache, so that different sessions of your app can access it, isn't provided "out of the box." MSAL for Python can be used in app types that don't have access to the file system--such as Web apps. To have a persistent token cache in an app that uses MSAL for Python, you must provide custom token cache serialization. @@ -13,7 +13,7 @@ The strategies for serializing the token cache differ depending on whether you'r ## Token cache for a public client application -Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the xref:msal.token_cache.serializabletokencache class reference documentation. +Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the class reference documentation. ## Token cache for a Web app (confidential client application) From af56c208e44e49ece2abaf619647a6fd88799c68 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 09:38:42 +0100 Subject: [PATCH 11/18] xref test 3 --- .../advanced/msal-python-token-cache-serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md index b2d44ec..82b3e74 100644 --- a/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md +++ b/msal-python-conceptual/advanced/msal-python-token-cache-serialization.md @@ -5,7 +5,7 @@ description: Learn how to serialize token cache using MSAL for Python # Custom token cache serialization in MSAL for Python -In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of . +In Microsoft Authentication Library (MSAL) for Python, an in-memory token cache that persists for the duration of the app session, is provided by default when you create an instance of . Serialization of the token cache, so that different sessions of your app can access it, isn't provided "out of the box." MSAL for Python can be used in app types that don't have access to the file system--such as Web apps. To have a persistent token cache in an app that uses MSAL for Python, you must provide custom token cache serialization. @@ -13,7 +13,7 @@ The strategies for serializing the token cache differ depending on whether you'r ## Token cache for a public client application -Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the class reference documentation. +Public client applications run on a user's device and manage tokens for a single user. In this case, you could serialize the entire cache into a file. Remember to provide file locking if your app, or another app, can access the cache concurrently. For a simple example of how to serialize a token cache to a file without locking, see the example in the class reference documentation. ## Token cache for a Web app (confidential client application) From 7686fd9e61b027daf668aa01d805bb3c5952b330 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 09:55:11 +0100 Subject: [PATCH 12/18] xref test 4 --- msal-python-conceptual/advanced/migrate-python-adal-msal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index 42be336..dd0fdeb 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -45,7 +45,7 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ------------------- | ------------------- | | [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](/python/api/msal/msal.application.publicclientapplication) or [ConfidentialClientApplication](/python/api/msal/msal.application.confidentialclientapplication) | | N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-interactive) | -| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow) | +| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow) | | [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) | | [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) | | [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [ClientApplication.acquire_token_by_refresh_token()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-refresh-token) | From 9d256d2b7afddb7f86477c4348748e6b84ab946a Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:01:41 +0100 Subject: [PATCH 13/18] xref test 5 --- msal-python-conceptual/advanced/migrate-python-adal-msal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index dd0fdeb..4b4b95c 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -45,7 +45,7 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ------------------- | ------------------- | | [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](/python/api/msal/msal.application.publicclientapplication) or [ConfidentialClientApplication](/python/api/msal/msal.application.confidentialclientapplication) | | N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-interactive) | -| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow) | +| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow) | | [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) | | [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) | | [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [ClientApplication.acquire_token_by_refresh_token()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-refresh-token) | From c7775bd5c83bafd6eb41584db21036ea4b1b51a8 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:56:28 +0100 Subject: [PATCH 14/18] xrefs added --- .../advanced/migrate-python-adal-msal.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index 4b4b95c..625bf34 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -43,18 +43,18 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ADAL for Python API | MSAL for Python API | | ------------------- | ------------------- | -| [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | [PublicClientApplication](/python/api/msal/msal.application.publicclientapplication) or [ConfidentialClientApplication](/python/api/msal/msal.application.confidentialclientapplication) | -| N/A | [PublicClientApplication.acquire_token_interactive()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-interactive) | -| N/A | [ClientApplication.initiate_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow) | -| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | [ClientApplication.acquire_token_by_auth_code_flow()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) | -| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | [ClientApplication.acquire_token_silent()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) | -| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: [ClientApplication.acquire_token_by_refresh_token()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-refresh-token) | -| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | [PublicClientApplication.initiate_device_flow()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-initiate-device-flow) | -| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | [PublicClientApplication.acquire_token_by_device_flow()](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) | -| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | [ClientApplication.acquire_token_by_username_password()](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-username-password) | -| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | [ConfidentialClientApplication.acquire_token_for_client()](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-for-client) | -| N/A | [ConfidentialClientApplication.acquire_token_on_behalf_of()](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) | -| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | [SerializableTokenCache()](/python/api/msal/msal.token_cache.serializabletokencache) | +| [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | or | +| N/A | | +| N/A | | +| [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | | +| [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | | +| [acquire_token_with_refresh_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_refresh_token) | These two helpers are intended to be used during [migration](#migrate-existing-refresh-tokens-for-msal-python) only: | +| [acquire_user_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_user_code) | | +| [acquire_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_device_code) and [cancel_request_to_get_token_with_device_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.cancel_request_to_get_token_with_device_code) | | +| [acquire_token_with_username_password()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_username_password) | | +| [acquire_token_with_client_credentials()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_credentials) and [acquire_token_with_client_certificate()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_client_certificate) | | +| N/A | | +| [TokenCache()](https://adal-python.readthedocs.io/en/latest/#adal.TokenCache) | | | N/A | Cache with persistence, available from [MSAL Extensions](https://github.com/marstr/original-microsoft-authentication-extensions-for-python) | ## Migrate existing refresh tokens for MSAL Python From fa5e4fef66ee063930900f2f4b08361698cc463c Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:09:06 +0100 Subject: [PATCH 15/18] removing duplication --- .../advanced/migrate-python-adal-msal.md | 1 + msal-python-conceptual/advanced/msal-logging-python.md | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/msal-python-conceptual/advanced/migrate-python-adal-msal.md b/msal-python-conceptual/advanced/migrate-python-adal-msal.md index 625bf34..61f1d02 100644 --- a/msal-python-conceptual/advanced/migrate-python-adal-msal.md +++ b/msal-python-conceptual/advanced/migrate-python-adal-msal.md @@ -45,6 +45,7 @@ The following table lists an API in ADAL for Python, and the one to use in its p | ------------------- | ------------------- | | [AuthenticationContext](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext) | or | | N/A | | +| N/A | | | N/A | | | [acquire_token_with_authorization_code()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token_with_authorization_code) | | | [acquire_token()](https://adal-python.readthedocs.io/en/latest/#adal.AuthenticationContext.acquire_token) | | diff --git a/msal-python-conceptual/advanced/msal-logging-python.md b/msal-python-conceptual/advanced/msal-logging-python.md index 04608a7..b00aee0 100644 --- a/msal-python-conceptual/advanced/msal-logging-python.md +++ b/msal-python-conceptual/advanced/msal-logging-python.md @@ -7,6 +7,13 @@ description: Learn how to log errors and exceptions in MSAL for Python The Microsoft Authentication Library (MSAL) apps generate log messages that can help diagnose issues. An app can configure logging with a few lines of code, and have custom control over the level of detail and whether or not personal and organizational data is logged. We recommend you create an MSAL logging implementation and provide a way for users to submit logs when they have authentication issues. +Logging in MSAL Python is designed to use the standard Python logging mechanisms, so all your previous knowledge of Python logging applies to MSAL Python. + +* By default, the logging in any Python script is turned off. If you want to enable debug logging for ALL modules in your entire Python script, you use `logging.basicConfig(level=logging.DEBUG)`. +* Most of the MSAL Python logs are already in debug level, which would be turned off by default. But if you want to enable debug logging to debug the OTHER modules in your Python script, therefore want to silence MSAL, you simply turn off the logger used by MSAL Python: `logging.getLogger("msal").setLevel(logging.WARN)`. +* MSAL Python does not log Personal Identifiable Information (PII). So there is not even a turn-on-PII-logging toggle in MSAL Python. App developers could still use standard Python logging to log whatever content. By doing so, the app takes responsibility for safely handling highly sensitive data and following regulatory requirements. + + ## Logging levels MSAL provides several levels of logging detail: From a0922d40dc6c103995d4a355ea771fc5b6f80145 Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:10:22 +0100 Subject: [PATCH 16/18] remove unnecessary articles from TOC --- msal-python-conceptual/TOC.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msal-python-conceptual/TOC.yml b/msal-python-conceptual/TOC.yml index d11ba37..ac36c72 100644 --- a/msal-python-conceptual/TOC.yml +++ b/msal-python-conceptual/TOC.yml @@ -34,10 +34,6 @@ href: advanced/client-credentials.md - name: Handle SameSite cookie changes in Chrome href: /azure/active-directory/develop/howto-handle-samesite-cookie-changes-chrome-browser?tabs=python - - name: Migrate existing refresh tokens into MSAL Python - href: advanced/migrate.md - - name: Logging - href: advanced/logging.md - name: Instance metadata caching href: advanced/instance-metadata-caching.md - name: Client capabilities From 0d10c66b3ab172c6bbcff12719715d5c85b3709a Mon Sep 17 00:00:00 2001 From: Chris Werner <59959532+cilwerner@users.noreply.github.com> Date: Wed, 30 Aug 2023 11:02:32 +0100 Subject: [PATCH 17/18] final change --- msal-python-conceptual/advanced/msal-error-handling-python.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md index f8e8e29..cd6301a 100644 --- a/msal-python-conceptual/advanced/msal-error-handling-python.md +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -55,7 +55,7 @@ For example the network can go down or the server is overloaded. MSAL Python 1.11+ automatically performs one retry attempt for you. You may customize this behavior by following -[the `http client` customization instruction](xref:msal.application.ConfidentialClientApplication). +[the `http client` customization instructions](xref:msal.application.ConfidentialClientApplication). ### HTTP 429 From 90b7169585beaea99826eb04ecc21c2ab8001c6a Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Wed, 30 Aug 2023 08:49:20 -0700 Subject: [PATCH 18/18] Update msal-error-handling-python.md --- msal-python-conceptual/advanced/msal-error-handling-python.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msal-python-conceptual/advanced/msal-error-handling-python.md b/msal-python-conceptual/advanced/msal-error-handling-python.md index cd6301a..18fbaaa 100644 --- a/msal-python-conceptual/advanced/msal-error-handling-python.md +++ b/msal-python-conceptual/advanced/msal-error-handling-python.md @@ -55,7 +55,7 @@ For example the network can go down or the server is overloaded. MSAL Python 1.11+ automatically performs one retry attempt for you. You may customize this behavior by following -[the `http client` customization instructions](xref:msal.application.ConfidentialClientApplication). +[the `http_client` customization instructions](xref:msal.application.ConfidentialClientApplication). ### HTTP 429 @@ -76,4 +76,4 @@ for more details. ## Next steps -- Consider enabling [Logging in MSAL for Python](msal-logging-python.md) to help you diagnose and debug issues. \ No newline at end of file +- Consider enabling [Logging in MSAL for Python](msal-logging-python.md) to help you diagnose and debug issues.