Azure Ad Authentication Python Web Api
Solution 1:
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:
importadalcontext= 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:
- 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).
- 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.
- 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}')
Solution 2:
I have just got into this challenge to get data from some webapi that uses oauth2 with azure.
Didn't like the idea to use adal library, as adal is not supported anymore for our case and looks like with oauth2 I can get the token without requirement for new library.
I'm did it:
import requests
import json
defget_token(auth_url, client_id, scope, client_secret, grant_type = 'client_credentials'):
"""
return: tuple dict with access_token, status_code
{'access_token': 'tokenid'
'expires_in': 3600,
'ext_expires_in': 0,
'token_type': 'Bearer'}, 200
"""# Request access token:# https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-access-token
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
url =auth_url
data = { "client_id": client_id,
"scope": scope,
"client_secret": client_secret,
"grant_type": grant_type
}
# requests doc http://docs.python-requests.org/en/v0.10.7/user/quickstart/#custom-headers
r = requests.post(url=url, data=data, headers=headers)
return r.json(), r.status_code
# Change these vars to test:
auth_url = 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
client_id = '6731de76-14a6-49ae-97bc-6eba6914391e'
scope = 'https://company.onmicrosoft.com/some-unique-number-for-scope/.default'
client_secret = "client password secret here"
url = 'http://bioforestws-sandbox.group.upm.com/api/interface/sap/stockmovement'
get_token = get_token(auth_url, client_id, scope, client_secret)
access_token = get_token[0]['access_token']
header_token = {"Authorization": "Bearer {}".format(access_token)}
rt = requests.get(url=url_check, headers=header_token)
Post a Comment for "Azure Ad Authentication Python Web Api"