Flusso di credenziali client di Microsoft Identity Platform e OAuth 2.0
Il flusso di concessione di credenziali client OAuth 2.0 permette a un servizio Web (client riservato) di usare le proprie credenziali per l'autenticazione in caso di chiamata a un altro servizio Web, invece di rappresentare un utente. La concessione specificata in RFC 6749, talvolta denominata OAuth a due zampe, può essere usata per accedere alle risorse ospitate sul Web usando l'identità di un'applicazione. Questo tipo viene comunemente usato per le interazioni da server a server che devono essere eseguite in background, senza interazione immediata con un utente e viene spesso definito daemon o account di servizio.
Nel flusso delle credenziali client, le autorizzazioni vengono concesse direttamente all'applicazione stessa da un amministratore. Quando l'app presenta un token a una risorsa, la risorsa impone che l'app stessa abbia l'autorizzazione per eseguire un'azione poiché non è presente alcun utente coinvolto nell'autenticazione. Questo articolo illustra entrambi i passaggi necessari per:
Questo articolo descrive come programmare direttamente in base al protocollo nell'applicazione. Quando possibile, è consigliabile usare le librerie di autenticazione Microsoft (MSAL) supportate anziché acquisire i token e chiamare le API Web protette. È anche possibile fare riferimento alle app di esempio che usano MSAL. Come nota laterale, i token di aggiornamento non verranno mai concessi con questo flusso come client_id
e client_secret
(che sarebbe necessario per ottenere un token di aggiornamento) possono essere usati per ottenere invece un token di accesso.
Per un livello di garanzia superiore, Microsoft Identity Platform consente anche al servizio chiamante di eseguire l'autenticazione usando un certificato o credenziali federate anziché un segreto condiviso. Poiché vengono usate le credenziali proprie dell'applicazione, queste credenziali devono essere mantenute al sicuro. Non pubblicare mai tali credenziali nel codice sorgente, incorporarlo in pagine Web o usarlo in un'applicazione nativa ampiamente distribuita.
Diagramma del protocollo
L'intero flusso di credenziali client ha un aspetto simile a quello illustrato nel diagramma seguente. Ciascuno di questi passaggi viene descritto più avanti in questo articolo.
Ottenere l'autorizzazione diretta
Un'app riceve generalmente l'autorizzazione diretta per accedere a una risorsa in uno dei due modi:
- Tramite un elenco di controllo di accesso (ACL) per la risorsa
- Tramite l'assegnazione delle autorizzazioni dell'applicazione in Microsoft Entra ID
Questi due metodi sono i più comuni in Microsoft Entra ID ed è consigliabile per i client e le risorse che eseguono il flusso delle credenziali client. Una risorsa può anche scegliere di autorizzare i client in altri modi. Ciascun server di risorse può scegliere il metodo più adatto all'applicazione.
Elenchi di controllo di accesso
Un provider di risorse potrebbe imporre un controllo delle autorizzazioni in base a un elenco di ID applicazione (client) che riconosce e a cui concede uno specifico livello di accesso. Quando la risorsa riceve un token da Microsoft Identity Platform, può decodificare il token ed estrarre l'ID applicazione del client dalle appid
attestazioni e iss
. A quel punto, la risorsa verifica la presenza dell'applicazione nell'elenco di controllo di accesso (ACL) esistente. La granularità e il metodo relativi all'elenco possono variare in maniera sostanziale da risorsa a risorsa.
Un caso d'uso comune prevede l'uso di un ACL per eseguire test per un'applicazione Web o per un'API Web. L'API Web potrebbe fornire solo un sottoinsieme delle autorizzazioni complete a un client specifico. Per eseguire test end-to-end sull'API, è possibile creare un client di test che acquisisce token da Microsoft Identity Platform e quindi li invia all'API. L'API controlla quindi nell'ACL se è presente l'ID dell'applicazione del client di test per concedere accesso completo alle funzionalità dell'API. Se si usa questo tipo di ACL, assicurarsi di convalidare non solo il valore appid
del chiamante, ma verificare anche che il valore iss
del token sia attendibile.
Questo tipo di autorizzazione è comune per gli account daemon e di servizio che devono accedere ai dati di proprietà di utenti che dispongono di account Microsoft personale. Per i dati appartenenti a organizzazioni, è consigliabile acquisire l'autorizzazione necessaria tramite le autorizzazioni dell'applicazione.
Controllo dei token senza l'attestazione roles
Per abilitare questo modello di autorizzazione basato su ACL, Microsoft Entra ID non richiede che le applicazioni siano autorizzate a ottenere token per un'altra applicazione. Di conseguenza, i token solo app possono essere emessi senza un'attestazione roles
. Le applicazioni che espongono le API devono implementare i controlli delle autorizzazioni per accettare i token.
Se si vuole impedire alle applicazioni di ottenere token di accesso solo app senza ruolo per l'applicazione, assicurarsi che i requisiti di assegnazione siano abilitati per l'app. In questo modo gli utenti e le applicazioni senza ruoli assegnati potranno ottenere un token per questa applicazione.
Autorizzazioni dell'applicazione
Anziché usare elenchi di controllo di accesso, è possibile usare le API per esporre un set di autorizzazioni dell'applicazione. Questi vengono concessi a un'applicazione dall'amministratore di un'organizzazione e possono essere usati solo per accedere ai dati di proprietà di tale organizzazione e dei relativi dipendenti. Ad esempio, Microsoft Graph espone diverse autorizzazioni dell'applicazione per le operazioni seguenti:
- Lettura di e-mail in tutte le caselle e-mail
- Lettura e scrittura di e-mail in tutte le caselle e-mail
- Invio di e-mail come utente
- Leggi i dati della directory
Per usare i ruoli dell'app (autorizzazioni dell'applicazione) con la propria API (anziché Microsoft Graph), è prima necessario esporre i ruoli dell'app nella registrazione dell'app dell'API nell'interfaccia di amministrazione di Microsoft Entra. Configurare quindi i ruoli dell'app necessari selezionando tali autorizzazioni nella registrazione dell'app dell'applicazione client. Se non sono stati esposti ruoli dell'app nella registrazione dell'app dell'API, non sarà possibile specificare le autorizzazioni dell'applicazione per tale API nella registrazione dell'app dell'applicazione client nell'interfaccia di amministrazione di Microsoft Entra.
Quando si esegue l'autenticazione come applicazione (anziché con un utente), non è possibile usare le autorizzazioni delegate perché non esiste alcun utente per l'app per agire per conto dell'utente. È necessario usare le autorizzazioni dell'applicazione, note anche come ruoli dell'app, concesse da un amministratore o dal proprietario dell'API.
Per altre informazioni sulle autorizzazioni dell'applicazione, vedere Autorizzazioni e consenso.
Consigliato: accedere all'amministratore nell'app per assegnare i ruoli dell'app
In genere, durante la compilazione di un'applicazione che usa le autorizzazioni, l'app necessita di una pagina o vista che consenta all'amministratore di approvare le autorizzazioni dell'applicazione. Questa pagina può far parte del flusso di accesso dell'app, parte delle impostazioni dell'app o di un flusso di connessione dedicato. Spesso è opportuno che l'app mostri questa visualizzazione di connessione solo dopo che un utente ha eseguito l'accesso con un account Microsoft aziendale o dell'istituto di istruzione.
Se si accede all'utente nell'app, è possibile identificare l'organizzazione a cui appartiene l'utente prima di chiedere all'utente di approvare le autorizzazioni dell'applicazione. Sebbene non sia strettamente necessario, questo consente di creare un'esperienza più intuitiva per gli utenti. Per accedere all'utente, seguire le esercitazioni sui protocolli di Microsoft Identity Platform.
Richiedere le autorizzazioni da un amministratore di directory
Quando si è pronti per richiedere le autorizzazioni dall'amministratore dell'organizzazione, è possibile reindirizzare l'utente all'endpoint di consenso amministratore di Microsoft Identity Platform.
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&state=12345
&redirect_uri=http://localhost/myapp/permissions
Suggerimento pro: provare a incollare la richiesta seguente in un browser.
https://login.microsoftonline.com/common/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions
Parametro | Condizione | Descrizione |
---|---|---|
tenant |
Richiesto | Il tenant della directory da cui si desidera richiedere autorizzazioni. Può essere fornito nel formato di nome descrittivo o GUID. Se non si conosce il tenant di appartenenza dell'utente e si desidera consentire l'accesso con qualsiasi tentant, usare common . |
client_id |
Richiesto | ID applicazione (client) assegnato all'app dall'interfaccia di amministrazione Registrazioni app di Microsoft Entra. |
redirect_uri |
Richiesto | URI di reindirizzamento in cui si desidera che venga inviata la risposta per la gestione da parte dell'app. Deve corrispondere esattamente a uno degli URI di reindirizzamento registrati nel portale, ad eccezione del fatto che deve essere codificato con URL e può avere segmenti di percorso aggiuntivi. |
state |
Consigliato | Valore incluso nella richiesta che viene restituito anche nella risposta del token. Può trattarsi di una stringa di qualsiasi contenuto. Lo stato viene usato per codificare le informazioni sullo stato dell'utente nell'app prima dell'esecuzione della richiesta di autenticazione, ad esempio la pagina o la vista in cui si trovava. |
A questo punto, Microsoft Entra ID impone che solo un amministratore tenant possa accedere per completare la richiesta. L'amministratore dovrà approvare tutte le autorizzazioni dirette dell'applicazione richieste per l'app nel portale di registrazione.
Risposta riuscita
Se l'amministratore approva le autorizzazioni per l'applicazione, la risposta con esito positivo si presenta come segue:
GET http://localhost/myapp/permissions?tenant=aaaabbbb-0000-cccc-1111-dddd2222eeee&state=state=12345&admin_consent=True
Parametro | Descrizione |
---|---|
tenant |
Tenant della directory che ha concesso all'applicazione le autorizzazioni richieste, in formato GUID. |
state |
Valore incluso nella richiesta che verrà restituito anche nella risposta del token. Può trattarsi di una stringa di qualsiasi contenuto. Lo stato viene usato per codificare le informazioni sullo stato dell'utente nell'app prima dell'esecuzione della richiesta di autenticazione, ad esempio la pagina o la vista in cui si trovava. |
admin_consent |
Impostare su True. |
Risposta con errore
Se l'amministratore non approva le autorizzazioni per l'applicazione, la risposta di errore avrà l'aspetto seguente:
GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
Parametro | Descrizione |
---|---|
error |
Stringa di codice di errore che può essere usata per classificare i tipi di errori e correggerli. |
error_description |
Messaggio di errore specifico che consente di identificare la causa principale di un errore. |
Dopo aver ricevuto una risposta con esito positivo dall'endpoint di provisioning dell'app, l'applicazione ha ottenuto le autorizzazioni dirette dell'applicazione richieste. Successivamente, è possibile richiedere un token per la risorsa desiderata.
Acquisizione di un token
Dopo aver acquisito l'autorizzazione necessaria per l'applicazione, è possibile procedere con l'acquisizione dei token di accesso per le API. Per ottenere un token usando la concessione delle credenziali client, inviare una richiesta POST a /token
Microsoft Identity Platform. Esistono alcuni casi diversi:
- Richiesta di token di accesso con un segreto condiviso
- Richiesta di token di accesso con un certificato
- Richiesta di token di accesso con credenziali federate
Primo caso: richiesta del token di accesso con un segreto condiviso
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=A1bC2dE3f...&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
Parametro | Condizione | Descrizione |
---|---|---|
tenant |
Richiesto | Tenant di directory su cui l'applicazione intende agire, in formato di GUID o nome di dominio. |
client_id |
Richiesto | ID applicazione assegnato all'app. È possibile trovare queste informazioni nel portale in cui è stata registrata l'app. |
scope |
Richiesto | Il valore passato per il parametro scope nella richiesta deve essere l'identificatore della risorsa (URI ID applicazione) della risorsa desiderata, con l'aggiunta del suffisso .default . Tutti gli ambiti inclusi devono essere per una singola risorsa. L'inclusione degli ambiti per più risorse genererà un errore. Per l'esempio di Microsoft Graph, il valore deve essere https://graph.microsoft.com/.default . Questo valore indica a Microsoft Identity Platform che di tutte le autorizzazioni dirette dell'applicazione configurate per l'app, l'endpoint deve rilasciare un token per quelli associati alla risorsa che si vuole usare. Per altre informazioni sull'ambito /.default , vedere la documentazione relativa al consenso. |
client_secret |
Richiesto | Segreto client generato per l'app nel portale di registrazione delle app. Il segreto client deve essere codificato nell'URL prima dell'invio. È supportato anche il modello di autenticazione di base per fornire le credenziali nell'intestazione Autorizzazione, per RFC 6749 . |
grant_type |
Richiesto | Deve essere impostato su client_credentials . |
Secondo caso: richiesta del token di accesso con un certificato
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Parametro | Condizione | Descrizione |
---|---|---|
tenant |
Richiesto | Tenant di directory su cui l'applicazione intende agire, in formato di GUID o nome di dominio. |
client_id |
Richiesto | ID applicazione (client) assegnato all'app. |
scope |
Richiesto | Il valore passato per il parametro scope nella richiesta deve essere l'identificatore della risorsa (URI ID applicazione) della risorsa desiderata, con l'aggiunta del suffisso .default . Tutti gli ambiti inclusi devono essere per una singola risorsa. L'inclusione degli ambiti per più risorse genererà un errore. Per l'esempio di Microsoft Graph, il valore deve essere https://graph.microsoft.com/.default . Questo valore indica a Microsoft Identity Platform che di tutte le autorizzazioni dirette dell'applicazione configurate per l'app, l'endpoint deve rilasciare un token per quelli associati alla risorsa che si vuole usare. Per altre informazioni sull'ambito /.default , vedere la documentazione relativa al consenso. |
client_assertion_type |
Richiesto | Il valore deve essere impostato su urn:ietf:params:oauth:client-assertion-type:jwt-bearer . |
client_assertion |
Richiesto | Asserzione (token Web JSON) che devi creare e firmare con il certificato registrato come credenziali per l'applicazione. Leggere l'articolo relativo alle credenziali basate su certificato per informazioni sulla registrazione del certificato e il formato dell'asserzione. |
grant_type |
Richiesto | Deve essere impostato su client_credentials . |
I parametri per la richiesta basata su certificato differiscono in un solo modo rispetto alla richiesta basata su segreto condiviso: il client_secret
parametro viene sostituito dai client_assertion_type
parametri e client_assertion
.
Terzo caso: richiesta di token di accesso con credenziali federate
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Parametro | Condizione | Descrizione |
---|---|---|
client_assertion |
Richiesto | Asserzione (token Web JWT o JSON) ottenuta dall'applicazione da un altro provider di identità all'esterno di Microsoft Identity Platform, ad esempio Kubernetes. Le specifiche di questo token JWT devono essere registrate nell'applicazione come credenziale di identità federata. Leggere informazioni sulla federazione delle identità del carico di lavoro per informazioni su come configurare e usare le asserzioni generate da altri provider di identità. |
Tutto ciò che si trova nella richiesta è lo stesso del flusso basato su certificato, con l'eccezione cruciale dell'origine dell'oggetto client_assertion
. In questo flusso, l'applicazione non crea l'asserzione JWT stessa. L'app usa invece un token JWT creato da un altro provider di identità. Questa operazione è denominata federazione dell'identità del carico di lavoro, in cui l'identità delle app in un'altra piattaforma di identità viene usata per acquisire i token all'interno di Microsoft Identity Platform. Questo è più adatto per scenari tra cloud, ad esempio l'hosting del calcolo all'esterno di Azure, ma l'accesso alle API protette da Microsoft Identity Platform. Per informazioni sul formato richiesto di JWT creati da altri provider di identità, vedere il formato dell'asserzione.
Risposta riuscita
Una risposta con esito positivo da qualsiasi metodo è simile alla seguente:
{
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
Parametro | Descrizione |
---|---|
access_token |
Token di accesso richiesto. L'app può usare questo token per eseguire l'autenticazione alla risorsa protetta, ad esempio per un'API Web. |
token_type |
Indica il valore del tipo di token. L'unico tipo supportato da Microsoft Identity Platform è bearer . |
expires_in |
Periodo di validità di un token di accesso (in secondi). |
Avviso
Non tentare di convalidare o leggere i token per qualsiasi API di cui non si è proprietari, inclusi i token in questo esempio, nel codice. I token per servizi Microsoft possono usare un formato speciale che non verrà convalidato come token JWT e potrebbe anche essere crittografato per gli utenti consumer (account Microsoft). Durante la lettura dei token è uno strumento utile per il debug e l'apprendimento, non assumere dipendenze da questo nel codice o presupporre specifiche sui token che non sono per un'API che si controlla.
Risposta con errore
Una risposta di errore (400 Richiesta non valida) è simile alla seguente:
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
"error_codes": [
70011
],
"timestamp": "YYYY-MM-DD HH:MM:SSZ",
"trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
"correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
Parametro | Descrizione |
---|---|
error |
Stringa di codice di errore che può essere usata per classificare i tipi di errori che si verificano e correggerli. |
error_description |
Messaggio di errore specifico che consente di identificare la causa principale di un errore di autenticazione. |
error_codes |
Elenco dei codici di errore specifici del servizio token di sicurezza utile per la diagnostica. |
timestamp |
Data/ora in cui si è verificato l'errore. |
trace_id |
Identificatore univoco per la richiesta utile per la diagnostica. |
correlation_id |
Identificatore univoco per la richiesta utile per la diagnostica dei componenti. |
Usare un token
Ora che hai acquisito un token, usalo per effettuare richieste alla risorsa. Alla scadenza del token, ripetere la richiesta all'endpoint /token
per ottwnere un token di accesso aggiornato.
GET /v1.0/users HTTP/1.1
Host: graph.microsoft.com:443
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...
Provare il comando seguente nel terminale, assicurandosi di sostituire il token con il proprio.
curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG..." 'https://graph.microsoft.com/v1.0/users'
Esempi di codice e altra documentazione
Leggere la documentazione generale sulle credenziali client da Microsoft Authentication Library
Esempio | Piattaforma | Descrizione |
---|---|---|
active-directory-dotnetcore-daemon-v2 | .NET 6.0+ | Un'applicazione ASP.NET Core che visualizza gli utenti di un tenant che esegue query su Microsoft Graph usando l'identità dell'applicazione, anziché per conto di un utente. L'esempio illustra anche la variante in cui vengono usati certificati per l'autenticazione. |
active-directory-dotnet-daemon-v2 | ASP.NET MVC | Un'applicazione Web che sincronizza i dati da Microsoft Graph usando la propria identità, anziché per conto di un utente. |
ms-identity-javascript-nodejs-console | Node.js Console | Un'applicazione Node.js che visualizza gli utenti di un tenant eseguendo una query su Microsoft Graph usando l'identità dell'applicazione |