Python oauth2 get token

Acquire an access token (Python)

This example demonstrates how to call an external Python script to obtain an OAuth2 token. A valid OAuth2 access token is required by the implementation of the authentication delegate.

Prerequisites

  • Install Python 2.7 or newer.
  • Implement utils.h/cpp in your project.
  • Auth.py should be added to your project and exist in same directory as the binaries at build.
  • Complete (MIP) SDK setup and configuration. Among other tasks, you’ll register your client application in your Azure Active Directory (Azure AD) tenant. Azure AD will provide an application ID, also known as client ID, which is used in your token acquisition logic.

This code isn’t intended for production use. It may only be used for development and understanding auth concepts. The sample is cross-platform.

sample::auth::AcquireToken()

In the simple authentication example, we demonstrated a simple AcquireToken() function that took no parameters and returned a hard-coded token value. In this example, we’ll overload AcquireToken() to accept authentication parameters and call an external Python script to return the token.

auth.h

In auth.h, AcquireToken() is overloaded and the overloaded function and updated parameters are as follows:

//auth.h #include namespace sample < namespace auth < std::string AcquireToken( const std::string& userName, //A string value containing the user's UPN. const std::string& password, //The user's password in plaintext const std::string& clientId, //The Azure AD client ID (also known as Application ID) of your application. const std::string& resource, //The resource URL for which an OAuth2 token is required. Provided by challenge object. const std::string& authority); //The authentication authority endpoint. Provided by challenge object. >> 

The first three parameters will be provided by user input or hard coded in to your application. The last two parameters are provided by the SDK to the auth delegate.

auth.cpp

In auth.cpp, we add the overloaded function definition, then define the code necessary to call the Python script. The function accepts all of the provided parameters and passes them to the Python script. The script executes and returns the token in string format.

#include "auth.h" #include "utils.h" #include #include #include #include using std::string; using std::runtime_error; namespace sample < namespace auth < //This function implements token acquisition in the application by calling an external Python script. //The Python script requires username, password, clientId, resource, and authority. //Username, Password, and ClientId are provided by the user/developer //Resource and Authority are provided as part of the OAuth2Challenge object that is passed in by the SDK to the AuthDelegate. string AcquireToken( const string& userName, const string& password, const string& clientId, const string& resource, const string& authority) < string cmd = "python"; if (sample::FileExists("auth.py")) cmd += " auth.py -u "; else throw runtime_error("Unable to find auth script."); cmd += userName; cmd += " -p "; cmd += password; cmd += " -a "; cmd += authority; cmd += " -r "; cmd += resource; cmd += " -c "; // Replace with the Application ID provided during your Azure AD application registration. cmd += (!clientId.empty() ? clientId : ""); string result = sample::Execute(cmd.c_str()); if (result.empty()) throw runtime_error("Failed to acquire token. Ensure Python is installed correctly."); return result; > > > 

Python Script

This script acquires authentication tokens directly via ADAL for Python. This code is included only as a means to acquire auth tokens for use by the sample apps and is not intended for use in production. The script works only against tenants that support plain old username/password http authentication. MFA or certificate-based authentication will fail.

Читайте также:  Java button mouse event

Prior to running this sample, you must install ADAL for Python by running one of the following commands:

pip install adal pip3 install adal 
import getopt import sys import json import re from adal import AuthenticationContext def printUsage(): print('auth.py -u -p -a -r -c ') def main(argv): try: options, args = getopt.getopt(argv, 'hu:p:a:r:c:') except getopt.GetoptError: printUsage() sys.exit(-1) username = '' password = '' authority = '' resource = '' clientId = '' for option, arg in options: if option == '-h': printUsage() sys.exit() elif option == '-u': username = arg elif option == '-p': password = arg elif option == '-a': authority = arg elif option == '-r': resource = arg elif option == '-c': clientId = arg if username == '' or password == '' or authority == '' or resource == '' or clientId == '': printUsage() sys.exit(-1) # Find everything after the last '/' and replace it with 'token' if not authority.endswith('token'): regex = re.compile('^(.*[\/])') match = regex.match(authority) authority = match.group() authority = authority + username.split('@')[1] auth_context = AuthenticationContext(authority) token = auth_context.acquire_token_with_username_password(resource, username, password, clientId) print(token["accessToken"]) if __name__ == '__main__': main(sys.argv[1:]) 

Update AcquireOAuth2Token

Finally, update the AcquireOAuth2Token function in AuthDelegateImpl to call the overloaded AcquireToken function. The resource and authority URLs are obtained by reading challenge.GetResource() and challenge.GetAuthority() . The OAuth2Challenge is passed in to the auth delegate when the engine is added. This work is done by the SDK and requires no additional work on the part of the developer.

bool AuthDelegateImpl::AcquireOAuth2Token( const mip::Identity& /*identity*/, const OAuth2Challenge& challenge, OAuth2Token& token) < //call our AcquireToken function, passing in username, password, clientId, and getting the resource/authority from the OAuth2Challenge object string accessToken = sample::auth::AcquireToken(mUserName, mPassword, mClientId, challenge.GetResource(), challenge.GetAuthority()); token.SetAccessToken(accessToken); return true; >

When the engine is added, the SDK will call the `AcquireOAuth2Token function, passing in the challenge, executing the Python script, receiving a token, then presenting the token to the service.

Читайте также:  Python string formatting characters

Источник

OAuth for Requests¶

Requests is a very popular HTTP library for Python. Authlib enables OAuth 1.0 and OAuth 2.0 for Requests with its OAuth1Session , OAuth2Session and AssertionSession .

Requests OAuth 1.0¶

There are three steps in OAuth 1 Session to obtain an access token:

  1. fetch a temporary credential
  2. visit the authorization page
  3. exchange access token with the temporary credential

It shares a common API design with OAuth for HTTPX .

OAuth1Session¶

The requests integration follows our common guide of OAuth 1 Session . Follow the documentation in OAuth 1 Session instead.

OAuth1Auth¶

It is also possible to use OAuth1Auth directly with in requests. After we obtained access token from an OAuth 1.0 provider, we can construct an auth instance for requests:

auth = OAuth1Auth( client_id='YOUR-CLIENT-ID', client_secret='YOUR-CLIENT-SECRET', token='oauth_token', token_secret='oauth_token_secret', ) requests.get(url, auth=auth) 

Requests OAuth 2.0¶

In OAuth 2 Session , there are many grant types, including:

  1. Authorization Code Flow
  2. Implicit Flow
  3. Password Flow
  4. Client Credentials Flow

And also, Authlib supports non Standard OAuth 2.0 providers via Compliance Fix.

Follow the common guide of OAuth 2 Session to find out how to use requests integration of OAuth 2.0 flow.

Using client_secret_jwt in Requests¶

There are three default client authentication methods defined for OAuth2Session . But what if you want to use client_secret_jwt instead? client_secret_jwt is defined in RFC7523, use it for Requests:

from authlib.integrations.requests_client import OAuth2Session from authlib.oauth2.rfc7523 import ClientSecretJWT token_endpoint = 'https://example.com/oauth/token' session = OAuth2Session( 'your-client-id', 'your-client-secret', token_endpoint_auth_method=ClientSecretJWT(token_endpoint), ) session.fetch_token(token_endpoint) 

Using private_key_jwt in Requests¶

What if you want to use private_key_jwt client authentication method, here is the way with PrivateKeyJWT for Requests:

from authlib.integrations.requests_client import OAuth2Session from authlib.oauth2.rfc7523 import PrivateKeyJWT with open('your-private-key.pem', 'rb') as f: private_key = f.read() token_endpoint = 'https://example.com/oauth/token' session = OAuth2Session( 'your-client-id', private_key, token_endpoint_auth_method=PrivateKeyJWT(token_endpoint), ) session.fetch_token(token_endpoint) 

OAuth2Auth¶

Already obtained access token? We can use OAuth2Auth directly in requests. But this OAuth2Auth can not refresh token automatically for you. Here is how to use it in requests:

token = 'token_type': 'bearer', 'access_token': '. ', . > auth = OAuth2Auth(token) requests.get(url, auth=auth) 

Requests OpenID Connect¶

OpenID Connect is built on OAuth 2.0. It is pretty simple to communicate with an OpenID Connect provider via Authlib. With Authlib built-in OAuth 2.0 system and JsonWebToken (JWT), parsing OpenID Connect id_token could be very easy.

Understand how it works with OAuth 2 OpenID Connect .

Requests Service Account¶

The Assertion Framework of OAuth 2.0 Authorization Grants is also known as service account. With the implementation of AssertionSession , we can easily integrate with a “assertion” service.

Checking out an example of Google Service Account with AssertionSession .

Close Session Hint¶

Developers SHOULD close a Requests Session when the jobs are done. You can call .close() manually, or use a with context to automatically close the session:

session = OAuth2Session(client_id, client_secret) session.get(url) session.close() with OAuth2Session(client_id, client_secret) as session: session.get(url) 

Self-Signed Certificate¶

Self-signed certificate mutual-TLS method internet standard is defined in RFC8705 Section 2.2 .

For specifics development purposes only, you may need to disable SSL verification.

You can force all requests to disable SSL verification by setting your environment variable CURL_CA_BUNDLE=»» .

This solutions works because Python requests (and most of the packages) overwrites the default value for ssl verifications from environment variables CURL_CA_BUNDLE and REQUESTS_CA_BUNDLE .

This hack will only work with CURL_CA_BUNDLE , as you can see in requests/sessions.py

verify = (os.environ.get('REQUESTS_CA_BUNDLE') or os.environ.get('CURL_CA_BUNDLE')) 

Please remember to set the env variable only in you development environment.

Источник

Оцените статью