إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
This example demonstrates how to call an external Python script to obtain an OAuth 2.0 token. The authentication delegate implementation requires a valid OAuth 2.0 access token.
Prerequisites
To run the sample:
- Install Python 3.10 or newer.
- Implement utils.h/cpp in your project.
- Add
auth.pyto your project, in the same directory as the binaries at build time. - Complete Microsoft Information Protection (MIP) SDK setup and configuration. Among other tasks, you register your client application in your Microsoft Entra tenant. Microsoft Entra ID provides an application ID, also known as client ID, for your token acquisition logic.
This code isn't intended for production use. Use it only for development and to understand auth concepts. The sample is cross-platform.
sample::auth::AcquireToken()
The simple authentication example demonstrates a simple AcquireToken() function that takes no parameters and returns a hard-coded token value. This example overloads AcquireToken() to accept authentication parameters and call an external Python script to return the token.
auth.h
In auth.h, AcquireToken() is overloaded. The overloaded function and updated parameters are as follows:
//auth.h
#include <string>
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.
}
}
User input or your application provides the first three parameters. The SDK provides the last two parameters to the auth delegate.
auth.cpp
The auth.cpp file adds the overloaded function definition, then defines the code that calls the Python script. The function accepts all provided parameters and passes them to the Python script. The script runs and returns the token in string format.
#include "auth.h"
#include "utils.h"
#include <fstream>
#include <functional>
#include <memory>
#include <string>
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 <application-id> with the Application ID provided during your Azure AD application registration.
cmd += (!clientId.empty() ? clientId : "<application-id>");
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 by using Microsoft Authentication Library (MSAL) for Python. This code is included only to acquire auth tokens for use by the sample apps and isn't intended for use in production. The script works only against tenants that support username/password authentication. The script doesn't support multifactor authentication (MFA) or certificate-based authentication.
Note
Before you run this sample, install MSAL for Python by running one of the following commands:
pip install msal
pip3 install msal
import getopt
import sys
import json
import re
from msal import PublicClientApplication
def printUsage():
print('auth.py -u <username> -p <password> -a <authority> -r <resource> -c <clientId>')
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)
# ONLY FOR DEMO PURPOSES AND MSAL FOR PYTHON
# This shouldn't be required when using proper auth flows in production.
if authority.find('common') > 1:
authority = authority.split('/common')[0] + "/organizations"
app = PublicClientApplication(client_id=clientId, authority=authority)
result = None
if resource.endswith('/'):
resource += ".default"
else:
resource += "/.default"
# *DO NOT* use username/password authentication in production system.
# Instead, consider auth code flow and using a browser to fetch the token.
result = app.acquire_token_by_username_password(username=username, password=password, scopes=[resource])
print(result['access_token'])
if __name__ == '__main__':
main(sys.argv[1:])
Update AcquireOAuth2Token
Finally, update the AcquireOAuth2Token function in AuthDelegateImpl to call the overloaded AcquireToken function. Read challenge.GetResource() and challenge.GetAuthority() to obtain the resource and authority URLs. The SDK passes the OAuth2Challenge to the auth delegate when it adds the engine. This SDK behavior requires no extra work from 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 SDK adds the engine, it calls the AcquireOAuth2Token function. The function passes in the challenge, runs the Python script, receives a token, and presents the token to the service.