Ottenere i token

Esistono molti modi per acquisire un token con MSAL Python. Alcuni richiedono l'interazione dell'utente, mentre altri no. L'approccio usato per acquisire un token è diverso a seconda che lo sviluppatore stia creando un client pubblico (desktop o mobile) o un'applicazione client riservata (app Web, API Web o daemon come un servizio Windows).

Prerequisiti

Prima di acquisire i token con MSAL Python, vedere Informazioni sui tipi di applicazione client.

Ottenere l'account utente

Un'app può acquisire un token come se stesso o per conto di un utente. Per acquisire un token per conto di un utente, l'app deve conoscere l'account dell'utente. MSAL Python fornisce il get_accounts metodo per ottenere l'account dell'utente. Questo metodo è disponibile nelle classi PublicClientApplication e ConfidentialClientApplication. Il metodo restituisce un elenco di account con cui l'utente ha eseguito l'accesso in precedenza, ovvero esiste nella cache.

accounts = app.get_accounts(username=user.get("preferred_username"))

L'account selezionato dall'utente per l'accesso può essere usato in un secondo momento in acquire_token_silent() per trovare i token.

Flussi di assegnazione di token

Esistono diversi flussi di autenticazione che possono essere usati per acquisire token con MSAL Python. Per altre informazioni su questi flussi, vedere la documentazione di Microsoft Identity Platform.

Avvertimento

Usare sempre MSAL per ottenere token di sicurezza e chiamare API Web protette nelle app. Non consigliamo di implementare una logica personalizzata di acquisizione dei token. Questi flussi consentono di comprendere meglio il funzionamento delle cose. Se stai proteggendo un'applicazione web, consigliamo di usare la libreria identity. Questa libreria non viene ufficialmente gestita da Microsoft, ma implementa la maggior parte della logica necessaria per acquisire i token nelle app Web.

Interattivo vs silenzioso

MSAL Python supporta sia l'acquisizione interattiva sia quella silenziosa dei token. L'acquisizione interattiva del token richiede l'interazione dell'utente, mentre l'acquisizione silenziosa del token non la richiede. I client pubblici richiedono generalmente l'interazione dell'utente, mentre i client confidenziali si basano invece su credenziali preconfigurate, come certificati e chiavi segrete.

Usare il acquire_token_silent_with_error metodo per acquisire automaticamente un token. Questo metodo trova un token di accesso valido dalla cache o un token di aggiornamento valido dalla cache e quindi lo usa automaticamente per riscattare un nuovo token di accesso. Se nessuno dei due è vero, è necessario usare un metodo interattivo per acquisire il token.

Se l'app non si preoccupa dell'errore esatto di aggiornamento del token durante la ricerca nella cache dei token, è consigliabile usare il acquire_token_silent metodo .

Un esempio di utilizzo di questo metodo è come illustrato nel frammento di codice seguente.

if accounts:
    # If so, you could then somehow display these accounts and let end user choose
    chosen = accounts[0]
    result = app.acquire_token_silent(scopes=["your_scope"], account=chosen)
    
    # At this point, you can save you can update your cache if you are using token caching
    # check result variable, if its None then you should interactively acquire a token
    if not result:
        # So no suitable token exists in cache. Let's get a new one from Microsoft Entra.
        result = app.acquire_token_by_one_of_the_actual_method(..., scopes=["User.Read"])
    
    if "access_token" in result:
        access_token = result["access_token"]
    else:
        print(result.get("error"))  
        print(result.get("error_description"))
        print(result.get("correlation_id"))  # You may need this when reporting a bug

Sono disponibili diversi metodi per l'acquisizione interattiva dei token. Il metodo da usare dipende dal tipo di app che si sta creando e dal flusso di concessione di token applicabile allo scenario.

Acquisizione interattiva del token per i client pubblici

Le applicazioni client pubbliche non possono archiviare in modo sicuro un segreto e possono autenticare solo l'utente che interagisce con il prodotto. MSAL Python espone la logica di acquisizione dei token per le applicazioni pubbliche tramite PublicClientApplication. Di seguito sono riportati i diversi metodi disponibili per le applicazioni client pubbliche per acquisire i token.

Flusso del codice del dispositivo

Il flusso di codice del dispositivo viene usato per acquisire i token nelle applicazioni eseguite nei dispositivi che non hanno accesso a un Web browser. Queste sono applicazioni note come applicazioni headless. Questo flusso fornisce all'utente un URL e un codice. L'utente passa a un Web browser in un altro dispositivo, immette il codice e accede. Al termine dell'autenticazione, Microsoft Entra restituisce un token al dispositivo senza browser.

Per prima cosa, chiami il metodo initiate_device_flow.

flow = app.initiate_device_flow(scopes=config["scope"])
if "user_code" not in flow:
    raise ValueError(
        "Fail to create device flow. Err: %s" % json.dumps(flow, indent=4))

print(flow["message"])
sys.stdout.flush()  # Some terminal needs this to ensure the message is shown

# Ideally you should wait here, in order to save some unnecessary polling
# input("Press Enter after signing in from another device to proceed, CTRL+C to abort.")

Si passa quindi l'oggetto dizionario del flusso al metodo acquire_token_by_device_flow per ottenere il token. Per impostazione predefinita, questo metodo blocca il thread corrente. È possibile seguire queste istruzioni per abbreviare il tempo di blocco oppure disattivare anche il comportamento di blocco e quindi continuare a chiamare acquire_token_by_device_flow nel ciclo personalizzato.

result = app.acquire_token_by_device_flow(flow)

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))  

Una risposta corretta è un dizionario che contiene una chiave access_token.

Acquisire il token interattivo

MSAL Python offre anche la possibilità per le app client pubbliche (Desktop e dispositivi mobili) di acquisire i token come utente. L'utente accede tramite l'URL della richiesta di autorizzazione tramite un Web browser. Imposta l'URI di reindirizzamento della tua app su http://localhost nel centro di amministrazione di Microsoft Entra per la registrazione della tua app. Se si sceglie di usare il broker durante la creazione PublicClientApplication, l'app deve anche registrare ms-appx-web://Microsoft.AAD.BrokerPlugin/YOUR_CLIENT_ID come URI di reindirizzamento.

result = app.acquire_token_interactive(  # It automatically provides PKCE protection
    scopes=config["scope"])

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))  

Nome utente e password

Avvertimento

Questa API è stata deprecata per i flussi client pubblici a causa di rischi per la sicurezza, usare un flusso più sicuro. Seguire questa guida per indicazioni sulla migrazione.

Non è consigliabile usare questo approccio. È anche possibile ottenere un token con un nome utente e una password. MSAL Python fornisce il acquire_token_by_username_password metodo per questo caso d'uso. Non è consigliabile perché l'applicazione chiederà direttamente a un utente la password, ovvero un modello non sicuro.

Sono disponibili flussi più sicuri che è possibile usare. Per altre informazioni, vedere il materiale sussidiario sul flusso di autenticazione con nome utente e password .

result = app.acquire_token_by_username_password(
    username=config["username"], password=config["password"], scopes=config["scope"])

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))  

Acquisizione interattiva di token dei client confidenziali

Le applicazioni client riservate possono archiviare in modo sicuro un segreto e possono eseguire l'autenticazione sia per conto di un'applicazione che per conto di un determinato utente. MSAL Python offre agli sviluppatori vari metodi per ottenere token durante lo sviluppo di ConfidentialClientApplication.

Acquisire il token per il client

Acquisisci il token come applicazione usando le credenziali client e non per un utente. Ad esempio, questo può essere usato nelle applicazioni che elaborano gli utenti in batch e non in un determinato utente, ad esempio gli strumenti di sincronizzazione. MSAL Python fornisce il acquire_token_for_client metodo per eseguire questa operazione. A partire da MSAL Python 1.23, questo metodo cerca automaticamente il token nella cache e invia una richiesta al provider di identità solo in caso di cache miss.

result = app.acquire_token_for_client(scopes=config["scope"])

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))    

Acquisire il token per conto di

Nel caso di app Web o API Web che chiamano un'altra API Web downstream nel nome dell'utente, usare il flusso On Behalf Of per acquisire un token basato su un'asserzione utente. Ad esempio, SAML e JWT. L'app corrente è un servizio di livello intermedio chiamato con un token che rappresenta un utente finale. L'app corrente può usare tale token, noto anche come asserzione utente, per richiedere un altro token per accedere all'API Web downstream per conto dell'utente. L'app di livello intermedio non ha alcuna interazione dell'utente per ottenere il consenso. Per informazioni su come ottenere il consenso iniziale per l'app di livello intermedio, vedere la documentazione.

Ecco un esempio di codice che acquisisce un token di accesso usando il acquire_token_on_behalf_of metodo .

def get(self, request): # a web service endpoint receiving a request
    
    scopes = ["your-scopes"]
    downstream_api = "https://your-downstreamapi.com/resource" #your downstream API resource endpoint
    current_access_token = request.headers.get("Authorization", None)
    
    # initialize the app
    app = msal.ConfidentialClientApplication(...) # refer to initialization of the app documentation

    #acquire token on behalf of the user that called this API
    downstream_api_access_token = app.acquire_token_on_behalf_of(
        user_assertion=current_app_access_token.split(' ')[1],
        scopes=_scopes
    )

    if "access_token" in result:
        access_token = result["access_token"]
        # use access_token to call dowstream API e.g
        requests.get(downstream_api, headers={'Authorization': f'Bearer {downstream_api_access_token}'})
    else:
        print(result.get("error")) 

Acquisire il token in base al flusso del codice di autorizzazione

Per le app Web che eseguono l'autenticazione nel nome di un utente, acquisire i token tramite il codice di autorizzazione dopo aver lasciato l'utente accedere tramite l'URL della richiesta di autorizzazione. Questo è in genere il meccanismo usato da un'applicazione che consente all'utente di accedere e accedere alle API Web per questo particolare utente.

È prima di tutto necessario avviare il flusso del codice di autenticazione usando .initiate_auth_code_flow Questo metodo accetta tra gli altri parametri un URI di reindirizzamento e una stringa di stato. Il valore del parametro di stato è incluso anche nella risposta del token. Se questo valore è assente, MSAL Python genererà automaticamente un valore internamente. L'URI di reindirizzamento specificato deve corrispondere all'URI di reindirizzamento registrato nella Interfaccia di amministrazione di Microsoft Entra. Questo metodo restituisce il flusso del codice di autenticazione che è un dizionario contenente auth_uri e state. auth_uri è l'URL che l'utente deve visitare per accedere.

flow = app.initiate_auth_code_flow(
    scopes=config["scope"], redirect_uri=config["redirect_uri"], state="your-state-value")

if "error" in flow:
    print(flow.get("error"))

# Save the response somewhere e.g in session
session["auth_flow"] = flow

# At this point, the app should guide the user to visit the auth ur (session["auth_flow"]["auth_uri"])

La risposta ottenuta visitando gli endpoint dell'URI di autenticazione viene usata nel metodo acquire_token_by_auth_code_flow. Lo stato è un identificatore univoco che è possibile usare per verificare la risposta dal server di autorizzazione. L'utente deve acconsentire agli ambiti di autorizzazione durante l'accesso.

# The uth_response value from visiting the auth_uri endpoint is passed as a query string
# You can change this by passing a value to the response_mode in the initiate_auth_code_flow method
try:
    result = app.acquire_token_by_auth_code_flow(session.get("flow", {}), auth_response)
    
    if "access_token" in result:
        access_token = result["access_token"]
    else:
        print(result.get("error"))
except ValueError:  # Usually caused by CSRF
    pass  # Simply ignore them

Memorizzazione dei token nella cache in MSAL Python

Sia le applicazioni client pubbliche che riservate supportano la memorizzazione nella cache dei token, gestite direttamente da MSAL Python. Le applicazioni devono provare a ottenere un token dalla cache prima di basarsi su qualsiasi altro mezzo. Per altre informazioni, vedere modello di acquisizione di token consigliato.

Per rendere persistente la cache, gli sviluppatori devono configurare la logica di serializzazione della cache dei token .