Stai visualizzando la documentazione di Apigee Edge.
Consulta la
documentazione di Apigee X. info
Questo argomento descrive come utilizzare gli ambiti OAuth 2.0 su Apigee Edge.
Che cos'è l'ambito OAuth2?
Gli ambiti OAuth 2.0 forniscono un modo per limitare la quantità di accesso concessa a un token di accesso. Ad esempio, a un token di accesso rilasciato a un'app client può essere concesso l'accesso in LETTURA e SCRITTURA alle risorse protette o solo l'accesso in LETTURA. Puoi implementare le tue API per applicare qualsiasi ambito o combinazione di ambiti che preferisci. Pertanto, se un client riceve un token con ambito READ e tenta di chiamare un endpoint API che richiede l'accesso in SCRITTURA, la chiamata non andrà a buon fine.
In questo argomento, parleremo di come gli ambiti vengono assegnati ai token di accesso e di come Apigee Edge applica gli ambiti OAuth 2.0. Dopo aver letto questo argomento, potrai utilizzare gli ambiti con sicurezza.
Come vengono assegnati gli ambiti ai token di accesso?
Quando Edge genera un token di accesso, può assegnargli un ambito. Per capire come funziona, devi prima conoscere queste entità di Apigee Edge: prodotti API, sviluppatori e app per sviluppatori. Per un'introduzione, consulta Introduzione alla pubblicazione. Ti consigliamo di esaminare questo materiale, se necessario, prima di continuare.
Un token di accesso è una lunga stringa di caratteri dall'aspetto casuale che consente a Edge di verificare le richieste API in entrata (considerala come un sostituto delle credenziali nome utente/password tipiche). Tecnicamente, il token è una chiave che fa riferimento a una raccolta di metadati che ha il seguente aspetto:
{ "issued_at" : "1416962591727", "application_name" : "0d3e1d41-a59f-4d74-957e-d4e3275d4781", "scope" : "A", "status" : "approved", "api_product_list" : "[scopecheck1-bs0cSuqS9y]", "expires_in" : "1799", //--in seconds "developer.email" : "scopecheck1-AdBmANhsag@apigee.com", "organization_id" : "0", "token_type" : "BearerToken", "client_id" : "eTtB7w5lvk3DnOZNGReBlvGvIAeAywun", "access_token" : "ODm47ris5AlEty8TDc1itwYPe5MW", "organization_name" : "wwitman", "refresh_token_expires_in" : "0", //--in seconds "refresh_count" : "0" }
I metadati del token includono la stringa del token di accesso effettivo, le informazioni sulla scadenza, identificazione dell'app per sviluppatori, dello sviluppatore e dei prodotti associati al token. Noterai anche che i metadati includono anche "ambito".
Come viene assegnato l'ambito al token?
La prima chiave per comprendere l'ambito è ricordare che a ogni prodotto in un'app per sviluppatori possono essere assegnati zero o più ambiti. Questi ambiti possono essere assegnati al momento della creazione del prodotto o aggiunti in un secondo momento. Esistono come elenco di nomi e sono inclusi nei "metadati" associati a ogni prodotto.
Quando crei un'app per sviluppatori e vi aggiungi prodotti, Edge esamina tutti i prodotti in nell'app per sviluppatori e crea un elenco di tutti gli ambiti per questi prodotti (l'elenco degli ambiti principali o globali dell'app, ovvero un'unione di tutti gli ambiti riconosciuti).
Quando un'app client richiede un token di accesso ad Apigee Edge, può facoltativamente specificare gli ambiti che vuole associare al token. Ad esempio, la seguente richiesta chiede l'ambito "A". Ovvero, il client chiede al server di autorizzazione (Edge) di generare un token di accesso con ambito "A" (che concede all'app l'autorizzazione a chiamare le API con ambito "A"). L'app invia una richiesta POST come questa:
curl -i -X POST -H Authorization: Basic Mg12YTk2UkEIyIBCrtro1QpIG -H content-type:application/x-www-form-urlencoded http://myorg-test.apigee.net/oauth/token?grant_type=client_credentials&scope=A
Che cosa succede?
Quando Edge riceve questa richiesta, sa quale app sta effettuando la richiesta e quale
app per sviluppatori ha registrato il client (le chiavi ID client e secret client sono codificate nell'
intestazione di autenticazione di base). Poiché è incluso il parametro di query scope, Edge deve
decidere se uno dei prodotti API associati all'app per sviluppatori ha l'ambito "A". In caso affermativo,
viene generato un token di accesso con ambito "A". Un altro modo per interpretare questa situazione è che il parametro di query dell'ambito
è una sorta di filtro. Se l'app per sviluppatori riconosce gli ambiti "A, B, X" e il
parametro di query specifica "scope=X Y Z", al token verrà assegnato solo l'ambito "X".
Che cosa succede se il client non allega un parametro dell'ambito? In questo caso, Edge genera un token che include tutti gli ambiti riconosciuti dall'app per sviluppatori. È importante capire che il comportamento predefinito consiste nel restituire un token di accesso che contiene l' unione di tutti gli ambiti per tutti i prodotti inclusi nell'app per sviluppatori.
Se nessuno dei prodotti associati a un'app per sviluppatori specifica gli ambiti e un token ha un ambito, le chiamate effettuate con quel token non andranno a buon fine.
Supponiamo che un'app per sviluppatori riconosca questi ambiti: A B C D. Questo è l'elenco principale degli ambiti dell'app. Potrebbe essere che un prodotto nell'app abbia gli ambiti A e B e un secondo abbia gli ambiti C
e D o qualsiasi combinazione. Se il client non specifica un parametro scope (o se
specifica un parametro scope senza valore), al token verranno concessi tutti e quattro gli ambiti: A, B, C,
e D. Anche in questo caso, il token riceve un insieme di ambiti che è l'unione di tutti gli ambiti riconosciuti
dall'app per sviluppatori.
Esiste un altro caso in cui il comportamento predefinito consiste nel restituire un token di accesso con tutti gli
ambiti riconosciuti, ovvero quando la policy GenerateAccessToken (la policy Apigee Edge che
genera i token di accesso) non specifica un elemento <Scope>.
Ad esempio, ecco una policy GenerateAccessToken in cui <Scope>
è specificato. Se l'elemento <Scope> manca (o se è
presente ma vuoto), viene eseguito il comportamento predefinito.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-GenerateAccessToken"> <DisplayName>OAuthV2 - Generate Access Token</DisplayName> <Attributes> <Attribute name='hello' ref='system.time' display='false'>value1</Attribute> </Attributes> <Scope>request.queryparam.scope</Scope> <GrantType>request.formparam.grant_type</GrantType> <ExternalAuthorization>false</ExternalAuthorization> <Operation>GenerateAccessToken</Operation> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <GenerateResponse enabled="true"/> </OAuthV2>
Come vengono applicati gli ambiti?
Innanzitutto, ricorda che su Apigee Edge i token di accesso vengono convalidati con la policy OAuthV2 (in genere posizionata all'inizio di un flusso proxy). La policy deve avere l' VerifyAccessToken operation specificata. Diamo un'occhiata a questa policy:
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
<DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
<ExternalAuthorization>false</ExternalAuthorization>
<Operation>VerifyAccessToken</Operation>
<Scope>A</Scope> <!-- Optional: space-separated list of scope names. -->
<GenerateResponse enabled="true"/>
</OAuthV2>Nota l'elemento <Scope>. Viene utilizzato per specificare gli ambiti accettati dalla policy.
In questo esempio, la policy avrà esito positivo solo se il token di accesso include l'ambito "A". Se questo elemento <Scope> viene omesso o non ha un valore, la policy ignora l'ambito del token di accesso.
Ora, con la possibilità di convalidare i token di accesso in base all'ambito, puoi progettare le tue API in modo da applicare ambiti specifici. Per farlo, devi progettare flussi personalizzati con policy VerifyAccessToken sensibili all'ambito allegate.
Supponiamo che la tua API abbia un flusso definito per l'endpoint /resourceA:
<Flow name="resourceA">
<Condition>(proxy.pathsuffix MatchesPath "/resourceA") and (request.verb = "GET")</Condition>
<Description>Get a resource A</Description>
<Request>
<Step>
<Name>OAuthV2-VerifyAccessTokenA</Name>
</Step>
</Request>
<Response>
<Step>
<Name>AssignMessage-CreateResponse</Name>
</Step>
</Response>
</Flow>Quando viene attivato questo flusso (arriva una richiesta con /resourceA nel suffisso del percorso
), viene chiamata immediatamente la policy OAuthV2-VerifyAccessTokenA. Questa policy verifica che
il token di accesso sia valido e cerca di vedere quali ambiti supporta il token. Se la policy è
configurata come nell'esempio riportato di seguito, con <Scope>A</Scope>, la policy avrà esito positivo solo
se il token di accesso ha l'ambito "A". In caso contrario, restituirà un errore.
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
<DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
<ExternalAuthorization>false</ExternalAuthorization>
<Operation>VerifyAccessToken</Operation>
<Scope>A</Scope>
<GenerateResponse enabled="true"/>
</OAuthV2>In sintesi, gli sviluppatori di API sono responsabili della progettazione dell'applicazione degli ambiti nelle loro API. Per farlo, creano flussi personalizzati per gestire ambiti specifici e allegano policy VerifyAccessToken per applicare questi ambiti.
Esempi di codice
Infine, diamo un'occhiata ad alcuni esempi di chiamate API per illustrare come i token ricevono gli ambiti e come vengono applicati gli ambiti.
Caso predefinito
Supponiamo che tu abbia un'app per sviluppatori con prodotti e che l'unione degli ambiti di questi prodotti sia: A, B e C. Questa chiamata API richiede un token di accesso, ma non specifica un parametro di query dell'ambito.
curl -X POST -H content-type:application/x-www-form-urlencoded http://wwitman-test.apigee.net/scopecheck1/token?grant_type=client_credentials
In questo caso, al token generato verranno assegnati gli ambiti A, B e C (il comportamento predefinito). I metadati del token avranno un aspetto simile al seguente:
{ "issued_at" : "1417016208588", "application_name" : "eb1a0333-5775-4116-9eb2-c36075ddc360", "scope" : "A B C", "status" : "approved", "api_product_list" : "[scopecheck1-yEgQbQqjRR]", "expires_in" : "1799", //--in seconds "developer.email" : "scopecheck1-yxiuHuZcDW@apigee.com", "organization_id" : "0", "token_type" : "BearerToken", "client_id" : "atGFvl3jgA0pJd05rXKHeNAC69naDmpW", "access_token" : "MveXpj4UYXol38thNoJYIa8fBGlI", "organization_name" : "wwitman", "refresh_token_expires_in" : "0", //--in seconds "refresh_count" : "0" }
Ora, supponiamo che tu abbia un endpoint API con ambito "A" (ovvero, il relativo VerifyAccessToken richiede l'ambito "A"). Ecco la policy VerifyAccessToken:
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
<DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
<ExternalAuthorization>false</ExternalAuthorization>
<Operation>VerifyAccessToken</Operation>
<Scope>A</Scope>
<GenerateResponse enabled="true"/>
</OAuthV2>Ecco una chiamata di esempio a un endpoint che applica l'ambito A:
curl -X GET -H Authorization: Bearer MveXpj4UYXol38thNoJYIa8fBGlI http://wwitman-test.apigee.net/scopecheck1/resourceA
Questa chiamata GET ha esito positivo:
{
"hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
}Ha esito positivo perché la policy VerifyAccessToken attivata quando viene chiamato l'endpoint richiede l'ambito A e al token di accesso sono stati concessi gli ambiti A, B e C, ovvero il comportamento predefinito.
Caso di filtro
Supponiamo che tu abbia un'app per sviluppatori con prodotti che hanno gli ambiti A, B, C e X. Richiedi
un token di accesso e includi il parametro di query scope, come segue:
curl -i -X POST -H content-type:application/x-www-form-urlencoded 'http://myorg-test.apigee.net/oauth/token?grant_type=client_credentials&scope=A X'
In questo caso, al token generato verranno assegnati gli ambiti A e X, perché sia A che X sono a ambiti validi. Ricorda che l'app per sviluppatori riconosce gli ambiti A, B, C e X. In questo caso, stai filtrando l'elenco dei prodotti API in base a questi ambiti. Se un prodotto ha l'ambito A o X, puoi configurare gli endpoint API che applicheranno questi ambiti. Se un prodotto non ha l'ambito A o X (ad esempio,ha B, C e Z), le API che applicano gli ambiti A o X non possono essere chiamate con il token.
Quando chiami l'API con il nuovo token:
curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG http://wwitman-test.apigee.net/scopecheck1/resourceX
Il token di accesso viene convalidato dal proxy API. Ad esempio:
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenX">
<DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
<ExternalAuthorization>false</ExternalAuthorization>
<Operation>VerifyAccessToken</Operation>
<Scope>A X</Scope>
<GenerateResponse enabled="true"/>
</OAuthV2>La chiamata GET ha esito positivo e restituisce una risposta. Ad esempio:
{
"hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
}
Ha esito positivo perché la policy VerifyAccessToken richiede l'ambito A o X e il token di accesso
include l'ambito A e X. Naturalmente, se l'elemento <Scope> fosse impostato su "B",
questa chiamata non andrebbe a buon fine.
Riepilogo
È importante capire come Apigee Edge gestisce gli ambiti OAuth 2.0. Ecco i punti chiave:
- Un'app per sviluppatori "riconosce" l'unione di tutti gli ambiti definiti per tutti i suoi prodotti.
- Quando un'app richiede un token di accesso, ha la possibilità di specificare gli ambiti che vuole avere. Spetta ad Apigee Edge (il server di autorizzazione) capire quali ambiti assegnerà effettivamente al token di accesso in base a (a) gli ambiti richiesti e (b) quelli riconosciuti dall'app per sviluppatori.
- Se Apigee Edge non è configurato per verificare l'ambito (l'elemento
<Scope>manca dalla policy VerifyAccessToken o è vuoto), la chiamata API avrà esito positivo a condizione che l'ambito incorporato nel token di accesso corrisponda a uno degli ambiti riconosciuti dall'app per sviluppatori registrata (uno degli ambiti nell'elenco "principale" degli ambiti dell'app). - Se a un token di accesso non sono associati ambiti, avrà esito positivo solo
nei casi in cui Edge non considera l'ambito (l'elemento
<Scope>manca dalla policy VerifyAccessToken o è vuoto).