Skip to content

Latest commit

 

History

History

README.md

topic sample
languages
python
azurepowershell
products
azure-active-directory
dotnet-core
office-ms-graph
description Python daemon console app using MSAL Python to get an access token and call Microsoft Graph (client secret variation).

A simple Python daemon console application calling Microsoft Graph with its own identity (client secret variation)

About this sample

Overview

This sample application shows how to use the Microsoft identity platform endpoint to access the data of Microsoft business customers in a long-running, non-interactive process. It uses the OAuth 2 client credentials grant to acquire an access token, which can be used to call the Microsoft Graph and access organizational data

The app is Python Console application. It gets the list of users in an Azure AD tenant by using Microsoft Authentication Library (MSAL) for Python to acquire a token.

Scenario

The console application:

  • gets a token from microsoft identity platform in its own name (without a user)
  • and then calls the Microsoft Graph /users endpoint to get the list of user, which it then displays (as Json blob)

Topology

For more information on the concepts used in this sample, be sure to read the Daemon app scenario and, if you're insterested in protocol details, the Microsoft identity platform endpoint client credentials protocol documentation.

Daemon applications can use two forms of secrets to authenticate themselves with Azure AD:

How to run this sample

To run this sample, you'll need:

Step 1: Clone or download this repository

From your shell or command line:

git clone https://github.com/Azure-Samples/ms-identity-python-daemon.git

Go to the "1-Call-MsGraph-WithSecret" folder

cd "1-Call-MsGraph-WithSecret"

or download and exact the repository .zip file.

Given that the name of the sample is pretty long, you might want to clone it in a folder close to the root of your hard drive, to avoid file size limitations on Windows.

Step 2: Register the sample with your Azure Active Directory tenant

There is one project in this sample. To register it, you can:

If you want to use this automation:

  1. On Windows run PowerShell and navigate to the root of the cloned directory

  2. In PowerShell run:

    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
  3. Run the script to create your Azure AD application and configure the code of the sample application accordingly.

    .\AppCreationScripts\Configure.ps1

    Other ways of running the scripts are described in App Creation Scripts

  4. Run the sample

    You'll need to install the dependencies using pip as follows:

     pip install -r requirements.txt

    Run confidential_client_secret_sample.py with the parameters for the app:

    python confidential_client_secret_sample.py parameters.json

If ou don't want to use this automation, follow the steps below

Choose the Azure AD tenant where you want to create your applications

As a first step you'll need to:

  1. Sign in to the Azure portal using either a work or school account or a personal Microsoft account.
  2. If your account is present in more than one Azure AD tenant, select Directory + Subscription at the top right corner in the menu on top of the page, and switch your portal session to the desired Azure AD tenant.
  3. In the left-hand navigation pane, select the Azure Active Directory service, and then select App registrations.

Register the client app (daemon-console)

  1. Navigate to the Microsoft identity platform for developers App registrations page.

  2. Select New registration.

    • In the Name section, enter a meaningful application name that will be displayed to users of the app, for example daemon-console.
    • In the Supported account types section, select Accounts in this organizational directory only ({tenant name}).
    • Select Register to create the application.
  3. On the app Overview page, find the Application (client) ID value and record it for later. You'll need it to configure the Visual Studio configuration file for this project.

  4. From the Certificates & secrets page, in the Client secrets section, choose New client secret:

    • Type a key description (of instance app secret),
    • Select a key duration of either In 1 year, In 2 years, or Never Expires.
    • When you press the Add button, the key value will be displayed, copy, and save the value in a safe location.
    • You'll need this key later to configure the project in Visual Studio. This key value will not be displayed again, nor retrievable by any other means, so record it as soon as it is visible from the Azure portal.
  5. In the list of pages for the app, select API permissions

    • Click the Add a permission button and then,
    • Ensure that the Microsoft APIs tab is selected
    • In the Commonly used Microsoft APIs section, click on Microsoft Graph
    • In the Application permissions section, ensure that the right permissions are checked: User.Read.All
    • Select the Add permissions button
  6. At this stage permissions are assigned correctly but the client app does not allow interaction. Therefore no consent can be presented via a UI and accepted to use the service app. Click the Grant/revoke admin consent for {tenant} button, and then select Yes when you are asked if you want to grant consent for the requested permissions for all account in the tenant. You need to be an Azure AD tenant admin to do this.

Step 3: Configure the sample to use your Azure AD tenant

In the steps below, "ClientID" is the same as "Application ID" or "AppId".

Open the parameters.json file

Configure the client project

Note: if you used the setup scripts, the changes below will have been applied for you

  1. Open the parameters.json file
  2. Find the string key organizations in the authority variable and replace the existing value with your Azure AD tenant name.
  3. Find the string key your_client_id and replace the existing value with the application ID (clientId) of the daemon-console application copied from the Azure portal.
  4. Find the string key The secret generated by AAD during your confidential app registration and replace the existing value with the key you saved during the creation of the daemon-console app, in the Azure portal.

Step 4: Run the sample

You'll need to install the dependencies using pip as follows:

pip install -r requirements.txt

Start the application, it will display some Json string containing the users in the tenant.

python confidential_client_secret_sample.py parameters.json

About the code

The relevant code for this sample is in the confidential_client_secret_sample.py file. The steps are:

  1. Create the MSAL confidential client application.

    Important note: even if we are building a console application, it is a daemon, and therefore a confidential client application, as it does not access Web APIs on behalf of a user, but on its own application behalf.

    app = msal.ConfidentialClientApplication(
        config["client_id"], authority=config["authority"],
        client_credential=config["secret"],
        )
  2. Define the scopes.

    Specific to client credentials, you don't specify, in the code, the individual scopes you want to access. You have statically declared them during the application registration step. Therefore the only possible scope is "resource/.default" (here "https://graph.microsoft.com/.default") which means "the static permissions defined in the application".

    In the parameters.json file you have:

    "scope": [ "https://graph.microsoft.com/.default" ],
  3. Acquire the token

    # The pattern to acquire a token looks like this.
    result = None
    
    # Firstly, looks up a token from cache
    # Since we are looking for token for the current app, NOT for an end user,
    # notice we give account parameter as None.
    result = app.acquire_token_silent(config["scope"], account=None)
    
    if not result:
    logging.info("No suitable token exists in cache. Let's get a new one from AAD.")
    result = app.acquire_token_for_client(scopes=config["scope"])
  4. Call the API

    In that case calling "https://graph.microsoft.com/v1.0/users" with the access token as a bearer token.

    if "access_token" in result:
        # Calling graph using the access token
        graph_data = requests.get(  # Use token to call downstream service
        config["endpoint"],
        headers={'Authorization': 'Bearer ' + result['access_token']}, ).json()
    print("Users from graph: " + str(graph_data))
    else:
        print(result.get("error"))
        print(result.get("error_description"))
        print(result.get("correlation_id"))  # You may need this when reporting a bug

Troubleshooting

Did you forget to provide admin consent? This is needed for daemon apps

If you get an error when calling the API Insufficient privileges to complete the operation., this is because the tenant administrator has not granted permissions to the application. See step 6 of Register the client app (daemon-console) above.

You will typically see, on the output window, something like the following:

Failed to call the Web Api: Forbidden
Content: {
  "error": {
    "code": "Authorization_RequestDenied",
    "message": "Insufficient privileges to complete the operation.",
    "innerError": {
      "request-id": "<a guid>",
      "date": "<date>"
    }
  }
}

Variation: daemon application using client credentials with certificates

See ../2-Call-MsGraph-WithCertificate

Community Help and Support

Use Stack Overflow to get support from the community. Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. Make sure that your questions or comments are tagged with [msal python].

If you find a bug in the sample, please raise the issue on GitHub Issues.

If you find a bug in Msal Python, please raise the issue on MSAL Python GitHub Issues.

To provide a recommendation, visit the following User Voice page.

Contributing

If you'd like to contribute to this sample, see CONTRIBUTING.MD.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

More information

For more information, see MSAL.NET's conceptual documentation:

For more information about the underlying protocol: