Reputation: 351
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.
Challenges:
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]
Upvotes: 4
Views: 27799
Reputation: 444
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
def get_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://learn.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)
Upvotes: 1
Reputation: 14376
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:
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:
The device code flow consists of:
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.
Upvotes: 7