.\" Man page generated from reStructuredText. . .TH "MSALPYTHON" "1" "Oct 28, 2022" "1.20.0" "MSAL Python" .SH NAME msalpython \- MSAL Python Documentation . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .sp You can find high level conceptual documentations in the project \fI\%README\fP\&. .sp There are many \fI\%different application scenarios\fP\&. MSAL Python supports some of them. \fBThe following diagram serves as a map. Locate your application scenario on the map.\fP \fBIf the corresponding icon is clickable, it will bring you to an MSAL Python sample for that scenario.\fP .INDENT 0.0 .IP \(bu 2 Most authentication scenarios acquire tokens on behalf of signed\-in users. .IP \(bu 2 There are also daemon apps. In these scenarios, applications acquire tokens on behalf of themselves with no user. .IP \(bu 2 There are other less common samples, such for ADAL\-to\-MSAL migration, \fI\%available inside the project code base\fP\&. .UNINDENT .sp The following section is the API Reference of MSAL Python. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Only APIs and their parameters documented in this section are part of public API, with guaranteed backward compatibility for the entire 1.x series. .sp Other modules in the source code are all considered as internal helpers, which could change at anytime in the future, without prior notice. .UNINDENT .UNINDENT .sp MSAL proposes a clean separation between \fI\%public client applications and confidential client applications\fP\&. .sp They are implemented as two separated classes, with different methods for different authentication scenarios. .SH PUBLICCLIENTAPPLICATION .INDENT 0.0 .TP .B class msal.PublicClientApplication(client_id, client_credential=None, **kwargs) .INDENT 7.0 .TP .B __init__(client_id, client_credential=None, **kwargs) Create an instance of application. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBclient_id\fP (\fIstr\fP) \-\- Your app has a client_id after you register it on AAD. .IP \(bu 2 \fBdict\fP\fB] \fP\fBclient_credential\fP (\fIUnion\fP\fI[\fP\fIstr\fP\fI,\fP) \-\- .sp For \fI\%PublicClientApplication\fP, you simply use \fINone\fP here. For \fI\%ConfidentialClientApplication\fP, it can be a string containing client secret, or an X509 certificate container in this form: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C { "private_key": "...\-\-\-\-\-BEGIN PRIVATE KEY\-\-\-\-\-...", "thumbprint": "A1B2C3D4E5F6...", "public_certificate": "...\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-... (Optional. See below.)", "passphrase": "Passphrase if the private_key is encrypted (Optional. Added in version 1.6.0)", } .ft P .fi .UNINDENT .UNINDENT .sp \fIAdded in version 0.5.0\fP: public_certificate (optional) is public key certificate which will be sent through \(aqx5c\(aq JWT header only for subject name and issuer authentication to support cert auto rolls. .sp Per \fI\%specs\fP, "the certificate containing the public key corresponding to the key used to digitally sign the JWS MUST be the first certificate. This MAY be followed by additional certificates, with each subsequent certificate being the one used to certify the previous one." However, your certificate\(aqs issuer may use a different order. So, if your attempt ends up with an error AADSTS700027 \- "The provided signature value did not match the expected signature value", you may try use only the leaf cert (in PEM/str format) instead. .sp \fIAdded in version 1.13.0\fP: It can also be a completely pre\-signed assertion that you\(aqve assembled yourself. Simply pass a container containing only the key "client_assertion", like this: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C { "client_assertion": "...a JWT with claims aud, exp, iss, jti, nbf, and sub..." } .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 \fBclient_claims\fP (\fIdict\fP) \-\- .sp \fIAdded in version 0.5.0\fP: It is a dictionary of extra claims that would be signed by by this \fI\%ConfidentialClientApplication\fP \(aqs private key. For example, you can use {"client_ip": "x.x.x.x"}. You may also override any of the following default claims: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C { "aud": the_token_endpoint, "iss": self.client_id, "sub": same_as_issuer, "exp": now + 10_min, "iat": now, "jti": a_random_uuid } .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 \fBauthority\fP (\fIstr\fP) \-\- .sp A URL that identifies a token authority. It should be of the format \fBhttps://login.microsoftonline.com/your_tenant\fP By default, we will use \fBhttps://login.microsoftonline.com/common\fP .sp \fIChanged in version 1.17\fP: you can also use predefined constant and a builder like this: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C from msal.authority import ( AuthorityBuilder, AZURE_US_GOVERNMENT, AZURE_CHINA, AZURE_PUBLIC) my_authority = AuthorityBuilder(AZURE_PUBLIC, "contoso.onmicrosoft.com") # Now you get an equivalent of # "https://login.microsoftonline.com/contoso.onmicrosoft.com" # You can feed such an authority to msal\(aqs ClientApplication from msal import PublicClientApplication app = PublicClientApplication("my_client_id", authority=my_authority, ...) .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 \fBvalidate_authority\fP (\fIbool\fP) \-\- (optional) Turns authority validation on or off. This parameter default to true. .IP \(bu 2 \fBcache\fP (\fI\%TokenCache\fP) \-\- Sets the token cache used by this ClientApplication instance. By default, an in\-memory cache will be created and used. .IP \(bu 2 \fBhttp_client\fP \-\- (optional) Your implementation of abstract class HttpClient Defaults to a requests session instance. Since MSAL 1.11.0, the default session would be configured to attempt one retry on connection error. If you are providing your own http_client, it will be your http_client\(aqs duty to decide whether to perform retry. .IP \(bu 2 \fBverify\fP \-\- (optional) It will be passed to the \fI\%verify parameter in the underlying requests library\fP This does not apply if you have chosen to pass your own Http client .IP \(bu 2 \fBproxies\fP \-\- (optional) It will be passed to the \fI\%proxies parameter in the underlying requests library\fP This does not apply if you have chosen to pass your own Http client .IP \(bu 2 \fBtimeout\fP \-\- (optional) It will be passed to the \fI\%timeout parameter in the underlying requests library\fP This does not apply if you have chosen to pass your own Http client .IP \(bu 2 \fBapp_name\fP \-\- (optional) You can provide your application name for Microsoft telemetry purposes. Default value is None, means it will not be passed to Microsoft. .IP \(bu 2 \fBapp_version\fP \-\- (optional) You can provide your application version for Microsoft telemetry purposes. Default value is None, means it will not be passed to Microsoft. .IP \(bu 2 \fBclient_capabilities\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- .sp (optional) Allows configuration of one or more client capabilities, e.g. ["CP1"]. .sp Client capability is meant to inform the Microsoft identity platform (STS) what this client is capable for, so STS can decide to turn on certain features. For example, if client is capable to handle \fIclaims challenge\fP, STS can then issue CAE access tokens to resources knowing when the resource emits \fIclaims challenge\fP the client will be capable to handle. .sp Implementation details: Client capability is implemented using "claims" parameter on the wire, for now. MSAL will combine them into \fI\%claims parameter\fP which you will later provide via one of the acquire\-token request. .IP \(bu 2 \fBazure_region\fP (\fIstr\fP) \-\- .sp AAD provides regional endpoints for apps to opt in to keep their traffic remain inside that region. .sp As of 2021 May, regional service is only available for \fBacquire_token_for_client()\fP sent by any of the following scenarios: .INDENT 2.0 .IP 1. 3 An app powered by a capable MSAL (MSAL Python 1.12+ will be provisioned) .IP 2. 3 An app with managed identity, which is formerly known as MSI. (However MSAL Python does not support managed identity, so this one does not apply.) .IP 3. 3 An app authenticated by \fI\%Subject Name/Issuer (SNI)\fP\&. .IP 4. 3 An app which already onboard to the region\(aqs allow\-list. .UNINDENT .sp This parameter defaults to None, which means region behavior remains off. .sp App developer can opt in to a regional endpoint, by provide its region name, such as "westus", "eastus2". You can find a full list of regions by running \fBaz account list\-locations \-o table\fP, or referencing to \fI\%this doc\fP\&. .sp An app running inside Azure Functions and Azure VM can use a special keyword \fBClientApplication.ATTEMPT_REGION_DISCOVERY\fP to auto\-detect region. .sp \fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 Setting \fBazure_region\fP to non\-\fBNone\fP for an app running outside of Azure Function/VM could hang indefinitely. .sp You should consider opting in/out region behavior on\-demand, by loading \fBazure_region=None\fP or \fBazure_region="westus"\fP or \fBazure_region=True\fP (which means opt\-in and auto\-detect) from your per\-deployment configuration, and then do \fBapp = ConfidentialClientApplication(..., azure_region=azure_region)\fP\&. .sp Alternatively, you can configure a short timeout, or provide a custom http_client which has a short timeout. That way, the latency would be under your control, but still less performant than opting out of region feature. .UNINDENT .UNINDENT .sp New in version 1.12.0. .IP \(bu 2 \fBexclude_scopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (optional) Historically MSAL hardcodes \fIoffline_access\fP scope, which would allow your app to have prolonged access to user\(aqs data. If that is unnecessary or undesirable for your app, now you can use this parameter to supply an exclusion list of scopes, such as \fBexclude_scopes = ["offline_access"]\fP\&. .IP \(bu 2 \fBhttp_cache\fP (\fIdict\fP) \-\- .sp MSAL has long been caching tokens in the \fBtoken_cache\fP\&. Recently, MSAL also introduced a concept of \fBhttp_cache\fP, by automatically caching some finite amount of non\-token http responses, so that \fIlong\-lived\fP \fBPublicClientApplication\fP and \fBConfidentialClientApplication\fP would be more performant and responsive in some situations. .sp This \fBhttp_cache\fP parameter accepts any dict\-like object. If not provided, MSAL will use an in\-memory dict. .sp If your app is a command\-line app (CLI), you would want to persist your http_cache across different CLI runs. The following recipe shows a way to do so: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C # Just add the following lines at the beginning of your CLI script import sys, atexit, pickle http_cache_filename = sys.argv[0] + ".http_cache" try: with open(http_cache_filename, "rb") as f: persisted_http_cache = pickle.load(f) # Take a snapshot except ( FileNotFoundError, # Or IOError in Python 2 pickle.UnpicklingError, # A corrupted http cache file ): persisted_http_cache = {} # Recover by starting afresh atexit.register(lambda: pickle.dump( # When exit, flush it back to the file. # It may occasionally overwrite another process\(aqs concurrent write, # but that is fine. Subsequent runs will reach eventual consistency. persisted_http_cache, open(http_cache_file, "wb"))) # And then you can implement your app as you normally would app = msal.PublicClientApplication( "your_client_id", ..., http_cache=persisted_http_cache, # Utilize persisted_http_cache ..., #token_cache=..., # You may combine the old token_cache trick # Please refer to token_cache recipe at # https://msal\-python.readthedocs.io/en/latest/#msal.SerializableTokenCache ) app.acquire_token_interactive(["your", "scope"], ...) .ft P .fi .UNINDENT .UNINDENT .sp Content inside \fBhttp_cache\fP are cheap to obtain. There is no need to share them among different apps. .sp Content inside \fBhttp_cache\fP will contain no tokens nor Personally Identifiable Information (PII). Encryption is unnecessary. .sp New in version 1.16.0. .IP \(bu 2 \fBinstance_discovery\fP (\fIboolean\fP) \-\- .sp Historically, MSAL would connect to a central endpoint located at \fBhttps://login.microsoftonline.com\fP to acquire some metadata, especially when using an unfamiliar authority. This behavior is known as Instance Discovery. .sp This parameter defaults to None, which enables the Instance Discovery. .sp If you know some authorities which you allow MSAL to operate with as\-is, without involving any Instance Discovery, the recommended pattern is: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C known_authorities = frozenset([ # Treat your known authorities as const "https://contoso.com/adfs", "https://login.azs/foo"]) \&... authority = "https://contoso.com/adfs" # Assuming your app will use this app1 = PublicClientApplication( "client_id", authority=authority, # Conditionally disable Instance Discovery for known authorities instance_discovery=authority not in known_authorities, ) .ft P .fi .UNINDENT .UNINDENT .sp If you do not know some authorities beforehand, yet still want MSAL to accept any authority that you will provide, you can use a \fBFalse\fP to unconditionally disable Instance Discovery. .sp New in version 1.19.0. .IP \(bu 2 \fBallow_broker\fP (\fIboolean\fP) \-\- .sp A broker is a component installed on your device. Broker implicitly gives your device an identity. By using a broker, your device becomes a factor that can satisfy MFA (Multi\-factor authentication). This factor would become mandatory if a tenant\(aqs admin enables a corresponding Conditional Access (CA) policy. The broker\(aqs presence allows Microsoft identity platform to have higher confidence that the tokens are being issued to your device, and that is more secure. .sp An additional benefit of broker is, it runs as a long\-lived process with your device\(aqs OS, and maintains its own cache, so that your broker\-enabled apps (even a CLI) could automatically SSO from a previously established signed\-in session. .sp This parameter defaults to None, which means MSAL will not utilize a broker. If this parameter is set to True, MSAL will use the broker whenever possible, and automatically fall back to non\-broker behavior. That also means your app does not need to enable broker conditionally, you can always set allow_broker to True, as long as your app meets the following prerequisite: .INDENT 2.0 .IP \(bu 2 Installed optional dependency, e.g. \fBpip install msal[broker]>=1.20,<2\fP\&. (Note that broker is currently only available on Windows 10+) .IP \(bu 2 Register a new redirect_uri for your desktop app as: \fBms\-appx\-web://Microsoft.AAD.BrokerPlugin/your_client_id\fP .IP \(bu 2 Tested your app in following scenarios: .INDENT 2.0 .IP \(bu 2 Windows 10+ .IP \(bu 2 PublicClientApplication\(aqs following methods:: acquire_token_interactive(), acquire_token_by_username_password(), acquire_token_silent() (or acquire_token_silent_with_error()). .IP \(bu 2 AAD and MSA accounts (i.e. Non\-ADFS, non\-B2C) .UNINDENT .UNINDENT .sp New in version 1.20.0. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_auth_code_flow(auth_code_flow, auth_response, scopes=None, **kwargs) Validate the auth response being redirected back, and obtain tokens. .sp It automatically provides nonce protection. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBauth_code_flow\fP (\fIdict\fP) \-\- The same dict returned by \fI\%initiate_auth_code_flow()\fP\&. .IP \(bu 2 \fBauth_response\fP (\fIdict\fP) \-\- A dict of the query string received from auth server. .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- .sp Scopes requested to access a protected API (a resource). .sp Most of the time, you can leave it empty. .sp If you requested user consent for multiple resources, here you will need to provide a subset of what you required in \fI\%initiate_auth_code_flow()\fP\&. .sp OAuth2 was designed mostly for singleton services, where tokens are always meant for the same resource and the only changes are in the scopes. In AAD, tokens can be issued for multiple 3rd party resources. You can ask authorization code for multiple resources, but when you redeem it, the token is for only one intended recipient, called audience. So the developer need to specify a scope so that we can restrict the token to be issued for the corresponding audience. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing "access_token" and/or "id_token", among others, depends on what scope was used. (See \fI\%https://tools.ietf.org/html/rfc6749#section\-5.1\fP) .IP \(bu 2 A dict containing "error", optionally "error_description", "error_uri". (It is either \fI\%this\fP or \fI\%that\fP) .IP \(bu 2 Most client\-side data error would result in ValueError exception. So the usage pattern could be without any protocol details: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C def authorize(): # A controller in a web app try: result = msal_app.acquire_token_by_auth_code_flow( session.get("flow", {}), request.args) if "error" in result: return render_template("error.html", result) use(result) # Token(s) are available in result and cache except ValueError: # Usually caused by CSRF pass # Simply ignore them return redirect(url_for("index")) .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_authorization_code(code, scopes, redirect_uri=None, nonce=None, claims_challenge=None, **kwargs) The second half of the Authorization Code Grant. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBcode\fP \-\- The authorization code returned from Authorization Server. .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- .sp (Required) Scopes requested to access a protected API (a resource). .sp If you requested user consent for multiple resources, here you will typically want to provide a subset of what you required in AuthCode. .sp OAuth2 was designed mostly for singleton services, where tokens are always meant for the same resource and the only changes are in the scopes. In AAD, tokens can be issued for multiple 3rd party resources. You can ask authorization code for multiple resources, but when you redeem it, the token is for only one intended recipient, called audience. So the developer need to specify a scope so that we can restrict the token to be issued for the corresponding audience. .IP \(bu 2 \fBnonce\fP \-\- If you provided a nonce when calling \fI\%get_authorization_request_url()\fP, same nonce should also be provided here, so that we\(aqll validate it. An exception will be raised if the nonce in id token mismatches. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_device_flow(flow, claims_challenge=None, **kwargs) Obtain token by a device flow object, with customizable polling effect. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBflow\fP (\fIdict\fP) \-\- A dict previously generated by \fI\%initiate_device_flow()\fP\&. By default, this method\(aqs polling effect will block current thread. You can abort the polling loop at any time, by changing the value of the flow\(aqs "expires_at" key to 0. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_refresh_token(refresh_token, scopes, **kwargs) Acquire token(s) based on a refresh token (RT) obtained from elsewhere. .sp You use this method only when you have old RTs from elsewhere, and now you want to migrate them into MSAL. Calling this method results in new tokens automatically storing into MSAL. .sp You do NOT need to use this method if you are already using MSAL. MSAL maintains RT automatically inside its token cache, and an access token can be retrieved when you call \fI\%acquire_token_silent()\fP\&. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBrefresh_token\fP (\fIstr\fP) \-\- The old refresh token, as a string. .IP \(bu 2 \fBscopes\fP (\fIlist\fP) \-\- The scopes associate with this old RT. Each scope needs to be in the Microsoft identity platform (v2) format. See \fI\%Scopes not resources\fP\&. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict contains "error" and some other keys, when error happened. .IP \(bu 2 A dict contains no "error" key means migration was successful. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_username_password(username, password, scopes, claims_challenge=None, **kwargs) Gets a token for a given resource via user credentials. .sp See this page for constraints of Username Password Flow. \fI\%https://github.com/AzureAD/microsoft\-authentication\-library\-for\-python/wiki/Username\-Password\-Authentication\fP .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBusername\fP (\fIstr\fP) \-\- Typically a UPN in the form of an email address. .IP \(bu 2 \fBpassword\fP (\fIstr\fP) \-\- The password. .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_interactive(scopes, prompt=None, login_hint=None, domain_hint=None, claims_challenge=None, timeout=None, port=None, extra_scopes_to_consent=None, max_age=None, parent_window_handle=None, on_before_launching_ui=None, **kwargs) Acquire token interactively i.e. via a local browser. .sp Prerequisite: In Azure Portal, configure the Redirect URI of your "Mobile and Desktop application" as \fBhttp://localhost\fP\&. If you opts in to use broker during \fBPublicClientApplication\fP creation, your app also need this Redirect URI: \fBms\-appx\-web://Microsoft.AAD.BrokerPlugin/YOUR_CLIENT_ID\fP .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP) \-\- It is a list of case\-sensitive strings. .IP \(bu 2 \fBprompt\fP (\fIstr\fP) \-\- By default, no prompt value will be sent, not even "none". You will have to specify a value explicitly. Its valid values are defined in Open ID Connect specs \fI\%https://openid.net/specs/openid\-connect\-core\-1_0.html#AuthRequest\fP .IP \(bu 2 \fBlogin_hint\fP (\fIstr\fP) \-\- Optional. Identifier of the user. Generally a User Principal Name (UPN). .IP \(bu 2 \fBdomain_hint\fP \-\- .sp Can be one of "consumers" or "organizations" or your tenant domain "contoso.com". If included, it will skip the email\-based discovery process that user goes through on the sign\-in page, leading to a slightly more streamlined user experience. More information on possible values \fI\%here\fP and \fI\%here\fP\&. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .IP \(bu 2 \fBtimeout\fP (\fIint\fP) \-\- This method will block the current thread. This parameter specifies the timeout value in seconds. Default value \fBNone\fP means wait indefinitely. .IP \(bu 2 \fBport\fP (\fIint\fP) \-\- The port to be used to listen to an incoming auth response. By default we will use a system\-allocated port. (The rest of the redirect_uri is hard coded as \fBhttp://localhost\fP\&.) .IP \(bu 2 \fBextra_scopes_to_consent\fP (\fIlist\fP) \-\- "Extra scopes to consent" is a concept only available in AAD. It refers to other resources you might want to prompt to consent for, in the same interaction, but for which you won\(aqt get back a token for in this particular operation. .IP \(bu 2 \fBmax_age\fP (\fIint\fP) \-\- .sp OPTIONAL. Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End\-User was actively authenticated. If the elapsed time is greater than this value, Microsoft identity platform will actively re\-authenticate the End\-User. .sp MSAL Python will also automatically validate the auth_time in ID token. .sp New in version 1.15. .IP \(bu 2 \fBparent_window_handle\fP (\fIint\fP) \-\- .sp OPTIONAL. If your app is a GUI app running on modern Windows system, and your app opts in to use broker, you are recommended to also provide its window handle, so that the sign in UI window will properly pop up on top of your window. .sp New in version 1.20.0. .IP \(bu 2 \fBon_before_launching_ui\fP (\fIfunction\fP) \-\- .sp A callback with the form of \fBlambda ui="xyz", **kwargs: print("A {} will be launched".format(ui))\fP, where \fBui\fP will be either "browser" or "broker". You can use it to inform your end user to expect a pop\-up window. .sp New in version 1.20.0. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing no "error" key, and typically contains an "access_token" key. .IP \(bu 2 A dict containing an "error" key, when token refresh failed. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_silent(scopes, account, authority=None, force_refresh=False, claims_challenge=None, **kwargs) Acquire an access token for given account, without user interaction. .sp It is done either by finding a valid access token from cache, or by finding a valid refresh token from cache and then automatically use it to redeem a new access token. .sp This method will combine the cache empty and refresh error into one return value, \fINone\fP\&. If your app does not care about the exact token refresh error during token cache look\-up, then this method is easier and recommended. .sp Internally, this method calls \fI\%acquire_token_silent_with_error()\fP\&. .INDENT 7.0 .TP .B Parameters \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing no "error" key, and typically contains an "access_token" key, if cache lookup succeeded. .IP \(bu 2 None when cache lookup does not yield a token. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_silent_with_error(scopes, account, authority=None, force_refresh=False, claims_challenge=None, **kwargs) Acquire an access token for given account, without user interaction. .sp It is done either by finding a valid access token from cache, or by finding a valid refresh token from cache and then automatically use it to redeem a new access token. .sp This method will differentiate cache empty from token refresh error. If your app cares the exact token refresh error during token cache look\-up, then this method is suitable. Otherwise, the other method \fI\%acquire_token_silent()\fP is recommended. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (Required) Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBaccount\fP \-\- one of the account object returned by \fI\%get_accounts()\fP, or use None when you want to find an access token for this client. .IP \(bu 2 \fBforce_refresh\fP \-\- If True, it will skip Access Token look\-up, and try to find a Refresh Token to obtain a new Access Token. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing no "error" key, and typically contains an "access_token" key, if cache lookup succeeded. .IP \(bu 2 None when there is simply no token in the cache. .IP \(bu 2 A dict containing an "error" key, when token refresh failed. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B get_accounts(username=None) Get a list of accounts which previously signed in, i.e. exists in cache. .sp An account can later be used in \fI\%acquire_token_silent()\fP to find its tokens. .INDENT 7.0 .TP .B Parameters \fBusername\fP \-\- Filter accounts with this username only. Case insensitive. .TP .B Returns A list of account objects. Each account is a dict. For now, we only document its "username" field. Your app can choose to display those information to end user, and allow user to choose one of his/her accounts to proceed. .UNINDENT .UNINDENT .INDENT 7.0 .TP .B get_authorization_request_url(scopes, login_hint=None, state=None, redirect_uri=None, response_type=\(aqcode\(aq, prompt=None, nonce=None, domain_hint=None, claims_challenge=None, **kwargs) Constructs a URL for you to start a Authorization Code Grant. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (Required) Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBstate\fP (\fIstr\fP) \-\- Recommended by OAuth2 for CSRF protection. .IP \(bu 2 \fBlogin_hint\fP (\fIstr\fP) \-\- Identifier of the user. Generally a User Principal Name (UPN). .IP \(bu 2 \fBredirect_uri\fP (\fIstr\fP) \-\- Address to return to upon receiving a response from the authority. .IP \(bu 2 \fBresponse_type\fP (\fIstr\fP) \-\- .sp Default value is "code" for an OAuth2 Authorization Code grant. .sp You could use other content such as "id_token" or "token", which would trigger an Implicit Grant, but that is \fI\%not recommended\fP\&. .IP \(bu 2 \fBprompt\fP (\fIstr\fP) \-\- By default, no prompt value will be sent, not even "none". You will have to specify a value explicitly. Its valid values are defined in Open ID Connect specs \fI\%https://openid.net/specs/openid\-connect\-core\-1_0.html#AuthRequest\fP .IP \(bu 2 \fBnonce\fP \-\- A cryptographically random value used to mitigate replay attacks. See also \fI\%OIDC specs\fP\&. .IP \(bu 2 \fBdomain_hint\fP \-\- .sp Can be one of "consumers" or "organizations" or your tenant domain "contoso.com". If included, it will skip the email\-based discovery process that user goes through on the sign\-in page, leading to a slightly more streamlined user experience. More information on possible values \fI\%here\fP and \fI\%here\fP\&. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns The authorization url as a string. .UNINDENT .UNINDENT .INDENT 7.0 .TP .B initiate_auth_code_flow(scopes, redirect_uri=None, state=None, prompt=None, login_hint=None, domain_hint=None, claims_challenge=None, max_age=None, response_mode=None) Initiate an auth code flow. .sp Later when the response reaches your redirect_uri, you can use \fI\%acquire_token_by_auth_code_flow()\fP to complete the authentication/authorization. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP) \-\- It is a list of case\-sensitive strings. .IP \(bu 2 \fBredirect_uri\fP (\fIstr\fP) \-\- Optional. If not specified, server will use the pre\-registered one. .IP \(bu 2 \fBstate\fP (\fIstr\fP) \-\- An opaque value used by the client to maintain state between the request and callback. If absent, this library will automatically generate one internally. .IP \(bu 2 \fBprompt\fP (\fIstr\fP) \-\- By default, no prompt value will be sent, not even "none". You will have to specify a value explicitly. Its valid values are defined in Open ID Connect specs \fI\%https://openid.net/specs/openid\-connect\-core\-1_0.html#AuthRequest\fP .IP \(bu 2 \fBlogin_hint\fP (\fIstr\fP) \-\- Optional. Identifier of the user. Generally a User Principal Name (UPN). .IP \(bu 2 \fBdomain_hint\fP \-\- .sp Can be one of "consumers" or "organizations" or your tenant domain "contoso.com". If included, it will skip the email\-based discovery process that user goes through on the sign\-in page, leading to a slightly more streamlined user experience. More information on possible values \fI\%here\fP and \fI\%here\fP\&. .IP \(bu 2 \fBmax_age\fP (\fIint\fP) \-\- .sp OPTIONAL. Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End\-User was actively authenticated. If the elapsed time is greater than this value, Microsoft identity platform will actively re\-authenticate the End\-User. .sp MSAL Python will also automatically validate the auth_time in ID token. .sp New in version 1.15. .IP \(bu 2 \fBresponse_mode\fP (\fIstr\fP) \-\- OPTIONAL. Specifies the method with which response parameters should be returned. The default value is equivalent to \fBquery\fP, which is still secure enough in MSAL Python (because MSAL Python does not transfer tokens via query parameter in the first place). For even better security, we recommend using the value \fBform_post\fP\&. In "form_post" mode, response parameters will be encoded as HTML form values that are transmitted via the HTTP POST method and encoded in the body using the application/x\-www\-form\-urlencoded format. Valid values can be either "form_post" for HTTP POST to callback URI or "query" (the default) for HTTP GET with parameters encoded in query string. More information on possible values \fIhere \fP and \fIhere \fP .UNINDENT .TP .B Returns The auth code flow. It is a dict in this form: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C { "auth_uri": "https://...", // Guide user to visit this "state": "...", // You may choose to verify it by yourself, // or just let acquire_token_by_auth_code_flow() // do that for you. "...": "...", // Everything else are reserved and internal } .ft P .fi .UNINDENT .UNINDENT .sp The caller is expected to: .INDENT 7.0 .IP 1. 3 somehow store this content, typically inside the current session, .IP 2. 3 guide the end user (i.e. resource owner) to visit that auth_uri, .IP 3. 3 and then relay this dict and subsequent auth response to \fI\%acquire_token_by_auth_code_flow()\fP\&. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B initiate_device_flow(scopes=None, **kwargs) Initiate a Device Flow instance, which will be used in \fI\%acquire_token_by_device_flow()\fP\&. .INDENT 7.0 .TP .B Parameters \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- Scopes requested to access a protected API (a resource). .TP .B Returns A dict representing a newly created Device Flow object. .INDENT 7.0 .IP \(bu 2 A successful response would contain "user_code" key, among others .IP \(bu 2 an error response would contain some other readable key/value pairs. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B remove_account(account) Sign me out and forget me from token cache .UNINDENT .UNINDENT .SH CONFIDENTIALCLIENTAPPLICATION .INDENT 0.0 .TP .B class msal.ConfidentialClientApplication(client_id, client_credential=None, authority=None, validate_authority=True, token_cache=None, http_client=None, verify=True, proxies=None, timeout=None, client_claims=None, app_name=None, app_version=None, client_capabilities=None, azure_region=None, exclude_scopes=None, http_cache=None, instance_discovery=None, allow_broker=None) .INDENT 7.0 .TP .B __init__(client_id, client_credential=None, authority=None, validate_authority=True, token_cache=None, http_client=None, verify=True, proxies=None, timeout=None, client_claims=None, app_name=None, app_version=None, client_capabilities=None, azure_region=None, exclude_scopes=None, http_cache=None, instance_discovery=None, allow_broker=None) Create an instance of application. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBclient_id\fP (\fIstr\fP) \-\- Your app has a client_id after you register it on AAD. .IP \(bu 2 \fBdict\fP\fB] \fP\fBclient_credential\fP (\fIUnion\fP\fI[\fP\fIstr\fP\fI,\fP) \-\- .sp For \fI\%PublicClientApplication\fP, you simply use \fINone\fP here. For \fI\%ConfidentialClientApplication\fP, it can be a string containing client secret, or an X509 certificate container in this form: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C { "private_key": "...\-\-\-\-\-BEGIN PRIVATE KEY\-\-\-\-\-...", "thumbprint": "A1B2C3D4E5F6...", "public_certificate": "...\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-... (Optional. See below.)", "passphrase": "Passphrase if the private_key is encrypted (Optional. Added in version 1.6.0)", } .ft P .fi .UNINDENT .UNINDENT .sp \fIAdded in version 0.5.0\fP: public_certificate (optional) is public key certificate which will be sent through \(aqx5c\(aq JWT header only for subject name and issuer authentication to support cert auto rolls. .sp Per \fI\%specs\fP, "the certificate containing the public key corresponding to the key used to digitally sign the JWS MUST be the first certificate. This MAY be followed by additional certificates, with each subsequent certificate being the one used to certify the previous one." However, your certificate\(aqs issuer may use a different order. So, if your attempt ends up with an error AADSTS700027 \- "The provided signature value did not match the expected signature value", you may try use only the leaf cert (in PEM/str format) instead. .sp \fIAdded in version 1.13.0\fP: It can also be a completely pre\-signed assertion that you\(aqve assembled yourself. Simply pass a container containing only the key "client_assertion", like this: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C { "client_assertion": "...a JWT with claims aud, exp, iss, jti, nbf, and sub..." } .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 \fBclient_claims\fP (\fIdict\fP) \-\- .sp \fIAdded in version 0.5.0\fP: It is a dictionary of extra claims that would be signed by by this \fI\%ConfidentialClientApplication\fP \(aqs private key. For example, you can use {"client_ip": "x.x.x.x"}. You may also override any of the following default claims: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C { "aud": the_token_endpoint, "iss": self.client_id, "sub": same_as_issuer, "exp": now + 10_min, "iat": now, "jti": a_random_uuid } .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 \fBauthority\fP (\fIstr\fP) \-\- .sp A URL that identifies a token authority. It should be of the format \fBhttps://login.microsoftonline.com/your_tenant\fP By default, we will use \fBhttps://login.microsoftonline.com/common\fP .sp \fIChanged in version 1.17\fP: you can also use predefined constant and a builder like this: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C from msal.authority import ( AuthorityBuilder, AZURE_US_GOVERNMENT, AZURE_CHINA, AZURE_PUBLIC) my_authority = AuthorityBuilder(AZURE_PUBLIC, "contoso.onmicrosoft.com") # Now you get an equivalent of # "https://login.microsoftonline.com/contoso.onmicrosoft.com" # You can feed such an authority to msal\(aqs ClientApplication from msal import PublicClientApplication app = PublicClientApplication("my_client_id", authority=my_authority, ...) .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 \fBvalidate_authority\fP (\fIbool\fP) \-\- (optional) Turns authority validation on or off. This parameter default to true. .IP \(bu 2 \fBcache\fP (\fI\%TokenCache\fP) \-\- Sets the token cache used by this ClientApplication instance. By default, an in\-memory cache will be created and used. .IP \(bu 2 \fBhttp_client\fP \-\- (optional) Your implementation of abstract class HttpClient Defaults to a requests session instance. Since MSAL 1.11.0, the default session would be configured to attempt one retry on connection error. If you are providing your own http_client, it will be your http_client\(aqs duty to decide whether to perform retry. .IP \(bu 2 \fBverify\fP \-\- .sp (optional) It will be passed to the \fI\%verify parameter in the underlying requests library\fP This does not apply if you have chosen to pass your own Http client .IP \(bu 2 \fBproxies\fP \-\- .sp (optional) It will be passed to the \fI\%proxies parameter in the underlying requests library\fP This does not apply if you have chosen to pass your own Http client .IP \(bu 2 \fBtimeout\fP \-\- .sp (optional) It will be passed to the \fI\%timeout parameter in the underlying requests library\fP This does not apply if you have chosen to pass your own Http client .IP \(bu 2 \fBapp_name\fP \-\- (optional) You can provide your application name for Microsoft telemetry purposes. Default value is None, means it will not be passed to Microsoft. .IP \(bu 2 \fBapp_version\fP \-\- (optional) You can provide your application version for Microsoft telemetry purposes. Default value is None, means it will not be passed to Microsoft. .IP \(bu 2 \fBclient_capabilities\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- .sp (optional) Allows configuration of one or more client capabilities, e.g. ["CP1"]. .sp Client capability is meant to inform the Microsoft identity platform (STS) what this client is capable for, so STS can decide to turn on certain features. For example, if client is capable to handle \fIclaims challenge\fP, STS can then issue CAE access tokens to resources knowing when the resource emits \fIclaims challenge\fP the client will be capable to handle. .sp Implementation details: Client capability is implemented using "claims" parameter on the wire, for now. MSAL will combine them into \fI\%claims parameter\fP which you will later provide via one of the acquire\-token request. .IP \(bu 2 \fBazure_region\fP (\fIstr\fP) \-\- .sp AAD provides regional endpoints for apps to opt in to keep their traffic remain inside that region. .sp As of 2021 May, regional service is only available for \fBacquire_token_for_client()\fP sent by any of the following scenarios: .INDENT 2.0 .IP 1. 3 An app powered by a capable MSAL (MSAL Python 1.12+ will be provisioned) .IP 2. 3 An app with managed identity, which is formerly known as MSI. (However MSAL Python does not support managed identity, so this one does not apply.) .IP 3. 3 An app authenticated by \fI\%Subject Name/Issuer (SNI)\fP\&. .IP 4. 3 An app which already onboard to the region\(aqs allow\-list. .UNINDENT .sp This parameter defaults to None, which means region behavior remains off. .sp App developer can opt in to a regional endpoint, by provide its region name, such as "westus", "eastus2". You can find a full list of regions by running \fBaz account list\-locations \-o table\fP, or referencing to \fI\%this doc\fP\&. .sp An app running inside Azure Functions and Azure VM can use a special keyword \fBClientApplication.ATTEMPT_REGION_DISCOVERY\fP to auto\-detect region. .sp \fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 Setting \fBazure_region\fP to non\-\fBNone\fP for an app running outside of Azure Function/VM could hang indefinitely. .sp You should consider opting in/out region behavior on\-demand, by loading \fBazure_region=None\fP or \fBazure_region="westus"\fP or \fBazure_region=True\fP (which means opt\-in and auto\-detect) from your per\-deployment configuration, and then do \fBapp = ConfidentialClientApplication(..., azure_region=azure_region)\fP\&. .sp Alternatively, you can configure a short timeout, or provide a custom http_client which has a short timeout. That way, the latency would be under your control, but still less performant than opting out of region feature. .UNINDENT .UNINDENT .sp New in version 1.12.0. .IP \(bu 2 \fBexclude_scopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (optional) Historically MSAL hardcodes \fIoffline_access\fP scope, which would allow your app to have prolonged access to user\(aqs data. If that is unnecessary or undesirable for your app, now you can use this parameter to supply an exclusion list of scopes, such as \fBexclude_scopes = ["offline_access"]\fP\&. .IP \(bu 2 \fBhttp_cache\fP (\fIdict\fP) \-\- .sp MSAL has long been caching tokens in the \fBtoken_cache\fP\&. Recently, MSAL also introduced a concept of \fBhttp_cache\fP, by automatically caching some finite amount of non\-token http responses, so that \fIlong\-lived\fP \fBPublicClientApplication\fP and \fBConfidentialClientApplication\fP would be more performant and responsive in some situations. .sp This \fBhttp_cache\fP parameter accepts any dict\-like object. If not provided, MSAL will use an in\-memory dict. .sp If your app is a command\-line app (CLI), you would want to persist your http_cache across different CLI runs. The following recipe shows a way to do so: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C # Just add the following lines at the beginning of your CLI script import sys, atexit, pickle http_cache_filename = sys.argv[0] + ".http_cache" try: with open(http_cache_filename, "rb") as f: persisted_http_cache = pickle.load(f) # Take a snapshot except ( FileNotFoundError, # Or IOError in Python 2 pickle.UnpicklingError, # A corrupted http cache file ): persisted_http_cache = {} # Recover by starting afresh atexit.register(lambda: pickle.dump( # When exit, flush it back to the file. # It may occasionally overwrite another process\(aqs concurrent write, # but that is fine. Subsequent runs will reach eventual consistency. persisted_http_cache, open(http_cache_file, "wb"))) # And then you can implement your app as you normally would app = msal.PublicClientApplication( "your_client_id", ..., http_cache=persisted_http_cache, # Utilize persisted_http_cache ..., #token_cache=..., # You may combine the old token_cache trick # Please refer to token_cache recipe at # https://msal\-python.readthedocs.io/en/latest/#msal.SerializableTokenCache ) app.acquire_token_interactive(["your", "scope"], ...) .ft P .fi .UNINDENT .UNINDENT .sp Content inside \fBhttp_cache\fP are cheap to obtain. There is no need to share them among different apps. .sp Content inside \fBhttp_cache\fP will contain no tokens nor Personally Identifiable Information (PII). Encryption is unnecessary. .sp New in version 1.16.0. .IP \(bu 2 \fBinstance_discovery\fP (\fIboolean\fP) \-\- .sp Historically, MSAL would connect to a central endpoint located at \fBhttps://login.microsoftonline.com\fP to acquire some metadata, especially when using an unfamiliar authority. This behavior is known as Instance Discovery. .sp This parameter defaults to None, which enables the Instance Discovery. .sp If you know some authorities which you allow MSAL to operate with as\-is, without involving any Instance Discovery, the recommended pattern is: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C known_authorities = frozenset([ # Treat your known authorities as const "https://contoso.com/adfs", "https://login.azs/foo"]) \&... authority = "https://contoso.com/adfs" # Assuming your app will use this app1 = PublicClientApplication( "client_id", authority=authority, # Conditionally disable Instance Discovery for known authorities instance_discovery=authority not in known_authorities, ) .ft P .fi .UNINDENT .UNINDENT .sp If you do not know some authorities beforehand, yet still want MSAL to accept any authority that you will provide, you can use a \fBFalse\fP to unconditionally disable Instance Discovery. .sp New in version 1.19.0. .IP \(bu 2 \fBallow_broker\fP (\fIboolean\fP) \-\- .sp A broker is a component installed on your device. Broker implicitly gives your device an identity. By using a broker, your device becomes a factor that can satisfy MFA (Multi\-factor authentication). This factor would become mandatory if a tenant\(aqs admin enables a corresponding Conditional Access (CA) policy. The broker\(aqs presence allows Microsoft identity platform to have higher confidence that the tokens are being issued to your device, and that is more secure. .sp An additional benefit of broker is, it runs as a long\-lived process with your device\(aqs OS, and maintains its own cache, so that your broker\-enabled apps (even a CLI) could automatically SSO from a previously established signed\-in session. .sp This parameter defaults to None, which means MSAL will not utilize a broker. If this parameter is set to True, MSAL will use the broker whenever possible, and automatically fall back to non\-broker behavior. That also means your app does not need to enable broker conditionally, you can always set allow_broker to True, as long as your app meets the following prerequisite: .INDENT 2.0 .IP \(bu 2 Installed optional dependency, e.g. \fBpip install msal[broker]>=1.20,<2\fP\&. (Note that broker is currently only available on Windows 10+) .IP \(bu 2 Register a new redirect_uri for your desktop app as: \fBms\-appx\-web://Microsoft.AAD.BrokerPlugin/your_client_id\fP .IP \(bu 2 Tested your app in following scenarios: .INDENT 2.0 .IP \(bu 2 Windows 10+ .IP \(bu 2 PublicClientApplication\(aqs following methods:: acquire_token_interactive(), acquire_token_by_username_password(), acquire_token_silent() (or acquire_token_silent_with_error()). .IP \(bu 2 AAD and MSA accounts (i.e. Non\-ADFS, non\-B2C) .UNINDENT .UNINDENT .sp New in version 1.20.0. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_auth_code_flow(auth_code_flow, auth_response, scopes=None, **kwargs) Validate the auth response being redirected back, and obtain tokens. .sp It automatically provides nonce protection. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBauth_code_flow\fP (\fIdict\fP) \-\- The same dict returned by \fI\%initiate_auth_code_flow()\fP\&. .IP \(bu 2 \fBauth_response\fP (\fIdict\fP) \-\- A dict of the query string received from auth server. .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- .sp Scopes requested to access a protected API (a resource). .sp Most of the time, you can leave it empty. .sp If you requested user consent for multiple resources, here you will need to provide a subset of what you required in \fI\%initiate_auth_code_flow()\fP\&. .sp OAuth2 was designed mostly for singleton services, where tokens are always meant for the same resource and the only changes are in the scopes. In AAD, tokens can be issued for multiple 3rd party resources. You can ask authorization code for multiple resources, but when you redeem it, the token is for only one intended recipient, called audience. So the developer need to specify a scope so that we can restrict the token to be issued for the corresponding audience. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing "access_token" and/or "id_token", among others, depends on what scope was used. (See \fI\%https://tools.ietf.org/html/rfc6749#section\-5.1\fP) .IP \(bu 2 A dict containing "error", optionally "error_description", "error_uri". (It is either \fI\%this\fP or \fI\%that\fP) .IP \(bu 2 Most client\-side data error would result in ValueError exception. So the usage pattern could be without any protocol details: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C def authorize(): # A controller in a web app try: result = msal_app.acquire_token_by_auth_code_flow( session.get("flow", {}), request.args) if "error" in result: return render_template("error.html", result) use(result) # Token(s) are available in result and cache except ValueError: # Usually caused by CSRF pass # Simply ignore them return redirect(url_for("index")) .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_authorization_code(code, scopes, redirect_uri=None, nonce=None, claims_challenge=None, **kwargs) The second half of the Authorization Code Grant. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBcode\fP \-\- The authorization code returned from Authorization Server. .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- .sp (Required) Scopes requested to access a protected API (a resource). .sp If you requested user consent for multiple resources, here you will typically want to provide a subset of what you required in AuthCode. .sp OAuth2 was designed mostly for singleton services, where tokens are always meant for the same resource and the only changes are in the scopes. In AAD, tokens can be issued for multiple 3rd party resources. You can ask authorization code for multiple resources, but when you redeem it, the token is for only one intended recipient, called audience. So the developer need to specify a scope so that we can restrict the token to be issued for the corresponding audience. .IP \(bu 2 \fBnonce\fP \-\- If you provided a nonce when calling \fI\%get_authorization_request_url()\fP, same nonce should also be provided here, so that we\(aqll validate it. An exception will be raised if the nonce in id token mismatches. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_refresh_token(refresh_token, scopes, **kwargs) Acquire token(s) based on a refresh token (RT) obtained from elsewhere. .sp You use this method only when you have old RTs from elsewhere, and now you want to migrate them into MSAL. Calling this method results in new tokens automatically storing into MSAL. .sp You do NOT need to use this method if you are already using MSAL. MSAL maintains RT automatically inside its token cache, and an access token can be retrieved when you call \fI\%acquire_token_silent()\fP\&. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBrefresh_token\fP (\fIstr\fP) \-\- The old refresh token, as a string. .IP \(bu 2 \fBscopes\fP (\fIlist\fP) \-\- .sp The scopes associate with this old RT. Each scope needs to be in the Microsoft identity platform (v2) format. See \fI\%Scopes not resources\fP\&. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict contains "error" and some other keys, when error happened. .IP \(bu 2 A dict contains no "error" key means migration was successful. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_by_username_password(username, password, scopes, claims_challenge=None, **kwargs) Gets a token for a given resource via user credentials. .sp See this page for constraints of Username Password Flow. \fI\%https://github.com/AzureAD/microsoft\-authentication\-library\-for\-python/wiki/Username\-Password\-Authentication\fP .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBusername\fP (\fIstr\fP) \-\- Typically a UPN in the form of an email address. .IP \(bu 2 \fBpassword\fP (\fIstr\fP) \-\- The password. .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_for_client(scopes, claims_challenge=None, **kwargs) Acquires token for the current confidential client, not for an end user. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (Required) Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_on_behalf_of(user_assertion, scopes, claims_challenge=None, **kwargs) Acquires token using on\-behalf\-of (OBO) flow. .sp The current app is a middle\-tier service which was called with a token representing an end user. The current app can use such token (a.k.a. a user assertion) to request another token to access downstream web API, on behalf of that user. See \fI\%detail docs here\fP . .sp The current middle\-tier app has no user interaction to obtain consent. See how to gain consent upfront for your middle\-tier app from this article. \fI\%https://docs.microsoft.com/en\-us/azure/active\-directory/develop/v2\-oauth2\-on\-behalf\-of\-flow#gaining\-consent\-for\-the\-middle\-tier\-application\fP .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBuser_assertion\fP (\fIstr\fP) \-\- The incoming token already received by this app .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- Scopes required by downstream API (a resource). .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns A dict representing the json response from AAD: .INDENT 7.0 .IP \(bu 2 A successful response would contain "access_token" key, .IP \(bu 2 an error response would contain "error" and usually "error_description". .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_silent(scopes, account, authority=None, force_refresh=False, claims_challenge=None, **kwargs) Acquire an access token for given account, without user interaction. .sp It is done either by finding a valid access token from cache, or by finding a valid refresh token from cache and then automatically use it to redeem a new access token. .sp This method will combine the cache empty and refresh error into one return value, \fINone\fP\&. If your app does not care about the exact token refresh error during token cache look\-up, then this method is easier and recommended. .sp Internally, this method calls \fI\%acquire_token_silent_with_error()\fP\&. .INDENT 7.0 .TP .B Parameters \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing no "error" key, and typically contains an "access_token" key, if cache lookup succeeded. .IP \(bu 2 None when cache lookup does not yield a token. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B acquire_token_silent_with_error(scopes, account, authority=None, force_refresh=False, claims_challenge=None, **kwargs) Acquire an access token for given account, without user interaction. .sp It is done either by finding a valid access token from cache, or by finding a valid refresh token from cache and then automatically use it to redeem a new access token. .sp This method will differentiate cache empty from token refresh error. If your app cares the exact token refresh error during token cache look\-up, then this method is suitable. Otherwise, the other method \fI\%acquire_token_silent()\fP is recommended. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (Required) Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBaccount\fP \-\- one of the account object returned by \fI\%get_accounts()\fP, or use None when you want to find an access token for this client. .IP \(bu 2 \fBforce_refresh\fP \-\- If True, it will skip Access Token look\-up, and try to find a Refresh Token to obtain a new Access Token. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns .INDENT 7.0 .IP \(bu 2 A dict containing no "error" key, and typically contains an "access_token" key, if cache lookup succeeded. .IP \(bu 2 None when there is simply no token in the cache. .IP \(bu 2 A dict containing an "error" key, when token refresh failed. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B get_accounts(username=None) Get a list of accounts which previously signed in, i.e. exists in cache. .sp An account can later be used in \fI\%acquire_token_silent()\fP to find its tokens. .INDENT 7.0 .TP .B Parameters \fBusername\fP \-\- Filter accounts with this username only. Case insensitive. .TP .B Returns A list of account objects. Each account is a dict. For now, we only document its "username" field. Your app can choose to display those information to end user, and allow user to choose one of his/her accounts to proceed. .UNINDENT .UNINDENT .INDENT 7.0 .TP .B get_authorization_request_url(scopes, login_hint=None, state=None, redirect_uri=None, response_type=\(aqcode\(aq, prompt=None, nonce=None, domain_hint=None, claims_challenge=None, **kwargs) Constructs a URL for you to start a Authorization Code Grant. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP\fI[\fP\fIstr\fP\fI]\fP) \-\- (Required) Scopes requested to access a protected API (a resource). .IP \(bu 2 \fBstate\fP (\fIstr\fP) \-\- Recommended by OAuth2 for CSRF protection. .IP \(bu 2 \fBlogin_hint\fP (\fIstr\fP) \-\- Identifier of the user. Generally a User Principal Name (UPN). .IP \(bu 2 \fBredirect_uri\fP (\fIstr\fP) \-\- Address to return to upon receiving a response from the authority. .IP \(bu 2 \fBresponse_type\fP (\fIstr\fP) \-\- .sp Default value is "code" for an OAuth2 Authorization Code grant. .sp You could use other content such as "id_token" or "token", which would trigger an Implicit Grant, but that is \fI\%not recommended\fP\&. .IP \(bu 2 \fBprompt\fP (\fIstr\fP) \-\- By default, no prompt value will be sent, not even "none". You will have to specify a value explicitly. Its valid values are defined in Open ID Connect specs \fI\%https://openid.net/specs/openid\-connect\-core\-1_0.html#AuthRequest\fP .IP \(bu 2 \fBnonce\fP \-\- .sp A cryptographically random value used to mitigate replay attacks. See also \fI\%OIDC specs\fP\&. .IP \(bu 2 \fBdomain_hint\fP \-\- .sp Can be one of "consumers" or "organizations" or your tenant domain "contoso.com". If included, it will skip the email\-based discovery process that user goes through on the sign\-in page, leading to a slightly more streamlined user experience. More information on possible values \fI\%here\fP and \fI\%here\fP\&. .IP \(bu 2 \fBclaims_challenge\fP \-\- The claims_challenge parameter requests specific claims requested by the resource provider in the form of a claims_challenge directive in the www\-authenticate header to be returned from the UserInfo Endpoint and/or in the ID Token and/or Access Token. It is a string of a JSON object which contains lists of claims being requested from these locations. .UNINDENT .TP .B Returns The authorization url as a string. .UNINDENT .UNINDENT .INDENT 7.0 .TP .B initiate_auth_code_flow(scopes, redirect_uri=None, state=None, prompt=None, login_hint=None, domain_hint=None, claims_challenge=None, max_age=None, response_mode=None) Initiate an auth code flow. .sp Later when the response reaches your redirect_uri, you can use \fI\%acquire_token_by_auth_code_flow()\fP to complete the authentication/authorization. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 \fBscopes\fP (\fIlist\fP) \-\- It is a list of case\-sensitive strings. .IP \(bu 2 \fBredirect_uri\fP (\fIstr\fP) \-\- Optional. If not specified, server will use the pre\-registered one. .IP \(bu 2 \fBstate\fP (\fIstr\fP) \-\- An opaque value used by the client to maintain state between the request and callback. If absent, this library will automatically generate one internally. .IP \(bu 2 \fBprompt\fP (\fIstr\fP) \-\- By default, no prompt value will be sent, not even "none". You will have to specify a value explicitly. Its valid values are defined in Open ID Connect specs \fI\%https://openid.net/specs/openid\-connect\-core\-1_0.html#AuthRequest\fP .IP \(bu 2 \fBlogin_hint\fP (\fIstr\fP) \-\- Optional. Identifier of the user. Generally a User Principal Name (UPN). .IP \(bu 2 \fBdomain_hint\fP \-\- .sp Can be one of "consumers" or "organizations" or your tenant domain "contoso.com". If included, it will skip the email\-based discovery process that user goes through on the sign\-in page, leading to a slightly more streamlined user experience. More information on possible values \fI\%here\fP and \fI\%here\fP\&. .IP \(bu 2 \fBmax_age\fP (\fIint\fP) \-\- .sp OPTIONAL. Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End\-User was actively authenticated. If the elapsed time is greater than this value, Microsoft identity platform will actively re\-authenticate the End\-User. .sp MSAL Python will also automatically validate the auth_time in ID token. .sp New in version 1.15. .IP \(bu 2 \fBresponse_mode\fP (\fIstr\fP) \-\- OPTIONAL. Specifies the method with which response parameters should be returned. The default value is equivalent to \fBquery\fP, which is still secure enough in MSAL Python (because MSAL Python does not transfer tokens via query parameter in the first place). For even better security, we recommend using the value \fBform_post\fP\&. In "form_post" mode, response parameters will be encoded as HTML form values that are transmitted via the HTTP POST method and encoded in the body using the application/x\-www\-form\-urlencoded format. Valid values can be either "form_post" for HTTP POST to callback URI or "query" (the default) for HTTP GET with parameters encoded in query string. More information on possible values \fIhere \fP and \fIhere \fP .UNINDENT .TP .B Returns The auth code flow. It is a dict in this form: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C { "auth_uri": "https://...", // Guide user to visit this "state": "...", // You may choose to verify it by yourself, // or just let acquire_token_by_auth_code_flow() // do that for you. "...": "...", // Everything else are reserved and internal } .ft P .fi .UNINDENT .UNINDENT .sp The caller is expected to: .INDENT 7.0 .IP 1. 3 somehow store this content, typically inside the current session, .IP 2. 3 guide the end user (i.e. resource owner) to visit that auth_uri, .IP 3. 3 and then relay this dict and subsequent auth response to \fI\%acquire_token_by_auth_code_flow()\fP\&. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B remove_account(account) Sign me out and forget me from token cache .UNINDENT .UNINDENT .SH TOKENCACHE .sp One of the parameters accepted by both \fIPublicClientApplication\fP and \fIConfidentialClientApplication\fP is the \fITokenCache\fP\&. .INDENT 0.0 .TP .B class msal.TokenCache This is considered as a base class containing minimal cache behavior. .sp Although it maintains tokens using unified schema across all MSAL libraries, this class does not serialize/persist them. See subclass \fI\%SerializableTokenCache\fP for details on serialization. .INDENT 7.0 .TP .B add() Handle a token obtaining event, and add tokens into cache. .sp Known side effects: This function modifies the input event in place. .UNINDENT .UNINDENT .sp You can subclass it to add new behavior, such as, token serialization. See \fISerializableTokenCache\fP for example. .INDENT 0.0 .TP .B class msal.SerializableTokenCache This serialization can be a starting point to implement your own persistence. .sp This class does NOT actually persist the cache on disk/db/etc.. Depending on your need, the following simple recipe for file\-based persistence may be sufficient: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C import os, atexit, msal cache = msal.SerializableTokenCache() if os.path.exists("my_cache.bin"): cache.deserialize(open("my_cache.bin", "r").read()) atexit.register(lambda: open("my_cache.bin", "w").write(cache.serialize()) # Hint: The following optional line persists only when state changed if cache.has_state_changed else None ) app = msal.ClientApplication(..., token_cache=cache) \&... .ft P .fi .UNINDENT .UNINDENT .INDENT 7.0 .TP .B Variables \fBhas_state_changed\fP (\fIbool\fP) \-\- Indicates whether the cache state in the memory has changed since last \fI\%serialize()\fP or \fI\%deserialize()\fP call. .UNINDENT .INDENT 7.0 .TP .B add(event, **kwargs) Handle a token obtaining event, and add tokens into cache. .sp Known side effects: This function modifies the input event in place. .UNINDENT .INDENT 7.0 .TP .B deserialize(state: Optional[str]) -> None Deserialize the cache from a state previously obtained by serialize() .UNINDENT .INDENT 7.0 .TP .B serialize() -> str Serialize the current cache state into a string. .UNINDENT .UNINDENT .SH AUTHOR Microsoft .SH COPYRIGHT 2022, Microsoft .\" Generated by docutils manpage writer. .