Azure AD Authentication Python Web API

13,426

The Authorization Code Grant flow (response_type=code) expects you to actually send the user, in a user-agent (i.e. a browser or a browser control) to that URL. The user will be presented with the sign-in process (e.g. username, password, multi-factor authentication, etc.) and when all that is done, the browser will be redirected to the redirect_uri.

This is all very simple if you're coding a web app as the client (you just send the user (in their browser) to the URL you've constructed, and you host a page at the redirect_uri to receive the authorization code after the sign-in completes). It seems, however, that you are maybe scripting a console app (or other app where it's impractical to send the user to a browser control where you can catch the eventual redirect). You have a few options, depending on whether or not the script is running in a highly-secure environment.

To call the API as an application

This is probably the simplest to implement, but requires the client to be running in a high-trust secure environment. The application will authenticate as itself (not as a user), obtain an access token, and make the API request. This is the OAuth 2.0 Client Credentials Grant flow.

You will need to:

  • Register your client app in Azure AD as a web app/web API (this is important, as it tells Azure AD that this is a confidential client, and allows you to associate credentials (a password or a certificate) for the app.
  • Declare that your client app requires access to your API (which would be registered as a different web app/web API).

With Python, the easiest way to do this is to use ADAL for Python. For example, to obtain an access token while authenticating with a certificate:

import adal
context = adal.AuthenticationContext('https://login.microsoftonline.com/{tenant-id}')
token = context.acquire_token_with_client_certificate(
    "https://api.example.com",
    "{client-id}",  
    '{certificate-content}', 
    '{certificate-thumbprint}')

See additional details on GitHub.

To call the API as a user, using the device code flow

The device flow allows limited-input experiences (e.g. think a TV, or a seldom-used console app) to obtain an OAuth 2.0 access token in the context of a user, while allowing the user to perform the actual sign-in on a different device with better input capabilities (e.g. on a smartphone or desktop computer).

You will need to:

  • Register your client app in Azure AD as a native client app (this is important, as it tells Azure AD that this is a public client, which allows the app to get an access token with delegated permissions without the app authenticating (because public clients can't keep a secret from the user).
  • Declare that your client app requires access to your API (which would be registered as a separate web app/web API).

The device code flow consists of:

  1. The client app makes a request to Azure AD to get an device code. This device code is displayed to the user (along with a URL).
  2. On a separate device (or, e.g. in full-fledged browser in the same device), the user visits the given URL, and inputs the given device code. The user is prompted to sign in and is shows a success message when they do so.
  3. Meanwhile, the client app periodically polls Azure AD to see if the user has redeemed the device code (and signed in). If yes, the client app received the access token.

With Python, it is again useful to use ADAL for Python. The request to get the device code would look like this:

context = adal.AuthenticationContext('https://login.microsoftonline.com/{tenant-id}')
code = context.acquire_user_code('https://api.example.com', '{client-id}')
print(code['message'])

The periodic polling requests look like this:

token = context.acquire_token_with_device_code('https://api.example.com', code, '{client-id}')

See additional details on GitHub.

Share:
13,426

Related videos on Youtube

Raj
Author by

Raj

Making my way into different programming languages.

Updated on June 04, 2022

Comments

  • Raj
    Raj almost 2 years

    I'm trying to get the user authenticated using OAuth2 and access resources. However, I'm having some issues doing so. Here are the details.

    1. I've registered the app as a Web Api on the Azure portal
    2. I want to write a python script through which I can request an authorization code and then the access token

    Challenges:

    1. I don't have redirect url. I'm not sure what I can use here
    2. When I use the link to get the authorization code in the browser, it asks me to sign in to Azure. How can I make sure that it asks me to login through the Python API as well?

    Here's the python script that I'm using just to get the authentication code:

    import requests
    import json
    
    '''Request Authorization code template
    
    https://login.microsoftonline.com/{tenant}/oauth2/authorize?
    client_id=6731de76-14a6-49ae-97bc-6eba6914391e
    &response_type=code
    &redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
    &response_mode=query
    &resource=https%3A%2F%2Fservice.contoso.com%2F
    &state=12345
    
    '''
    
    payload = {'client_id': '***', 'response_type': 'code', 'response_mode': 'query',
               'resource': '***'}
    get_authorization_code = requests.get('https://login.microsoftonline.com/tenant/oauth2/authorize',
                            params=payload, verify=False)
    print get_authorization_code
    

    Response for this code I get is : Response [200]

  • Raj
    Raj almost 7 years
    To be more specific, I would like to pull management information from the Azure AD using this script. Things like number of Apps registered with the AAD, total number of users and so on. Is this the correct direction I'm going in? Since I'm using this script, I've registered it as a Web API on the Azure AD. And from this App (once complete) I would like to access the management resources.