Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este exemplo demonstra como chamar um script Python externo para obter um token OAuth2. Um token de acesso OAuth2 válido é exigido pela implementação do delegado de autenticação.
Pré-requisitos
Para executar o exemplo:
- Instala Python 3.10 ou mais recente.
- Implementa utils.h/cpp no teu projeto.
- Auth.py deve ser adicionado ao seu projeto e estar no mesmo diretório que os binários no momento da compilação.
- Configuração completa do SDK Microsoft Information Protection (MIP). Entre outras tarefas, regista a sua aplicação cliente no seu tenant Microsoft Entra. O Microsoft Entra ID fornece um ID de aplicação, também conhecido como ID do cliente, que é utilizado na lógica de aquisição de tokens.
Este código não é destinado a uso em produção. Pode ser usado apenas para desenvolvimento e compreensão de conceitos de autenticação. A amostra é multiplataforma.
sample::auth::AcquireToken()
No exemplo de autenticação simples, demonstrámos uma função simples AcquireToken() que não tomava parâmetros e devolvea um valor de token codificado fixamente. Neste exemplo, sobrecarregamos o AcquireToken() para aceitar parâmetros de autenticação e chamamos um script Python externo para devolver o token.
auth.h
Em auth.h, AcquireToken() está sobrecarregado e a função sobrecarregada e os parâmetros atualizados são os seguintes:
//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.
}
}
Os três primeiros parâmetros são fornecidos pela entrada do utilizador ou codificados diretamente na aplicação. Os dois últimos parâmetros são fornecidos pelo SDK ao delegado de autenticação.
auth.cpp
Em auth.cpp, adicionamos a definição da função sobrecarregada e depois definimos o código necessário para chamar o script Python. A função aceita todos os parâmetros fornecidos e passa-os para o script Python. O script executa e devolve o token em formato de string.
#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
Este script adquire tokens de autenticação diretamente via Biblioteca de Autenticação da Microsoft (MSAL) para Python. Este código está incluído apenas como meio de adquirir tokens de autenticação para uso pelas aplicações de exemplo e não é destinado a ser usado em produção. O script funciona apenas contra inquilinos que suportam autenticação simples de nome de utilizador/palavra-passe. MFA ou autenticação baseada em certificados não são suportadas através deste script.
Observação
Antes de executar este exemplo, deve instalar o MSAL para Python executando um dos seguintes comandos:
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:])
Atualização de AcquireOAuth2Token
Finalmente, atualize a função AcquireOAuth2Token em AuthDelegateImpl para chamar a função sobrecarregada AcquireToken. As URLs de recursos e autoridades são obtidas lendo challenge.GetResource() e challenge.GetAuthority(). O OAuth2Challenge é passado ao delegado de autenticação quando o motor é adicionado. Este trabalho é feito pelo SDK e não requer trabalho adicional por parte do desenvolvedor.
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;
}
Quando o engine é adicionado, o SDK chama a função 'AcquireOAuth2Token, passando o desafio, executando o script Python, recebendo um token e depois apresentando-o ao serviço.