Wyświetlasz dokumentację Apigee Edge.
Przejdź do
dokumentacji Apigee X. info
W tym artykule omawiamy, jak używać zakresów OAuth 2.0 w Apigee Edge.
Co to jest zakres OAuth2?
Zakresy OAuth 2.0 umożliwiają ograniczenie zakresu dostępu przyznawanego tokenowi dostępu. Na przykład token dostępu wydany aplikacji klienckiej może mieć uprawnienia do odczytu i zapisu chronionych zasobów lub tylko do odczytu. Możesz zaimplementować interfejsy API, aby wymuszać dowolny zakres lub kombinację zakresów. Jeśli więc klient otrzyma token z zakresem READ i spróbuje wywołać punkt końcowy interfejsu API, który wymaga dostępu WRITE, wywołanie się nie powiedzie.
W tym artykule omówimy, jak zakresy są przypisywane do tokenów dostępu i jak Apigee Edge wymusza zakresy OAuth 2.0. Po przeczytaniu tego artykułu będziesz mieć pewność, że możesz używać zakresów z pewnością.
Jak zakresy są przypisywane do tokenów dostępu?
Gdy Edge generuje token dostępu, może przypisać do niego zakres. Aby zrozumieć, jak to się dzieje, musisz najpierw zapoznać się z tymi encjami Apigee Edge: usługami interfejsu API, deweloperami i aplikacjami deweloperów. Więcej informacji znajdziesz w artykule Wprowadzenie do publikowania. Jeśli to konieczne, przed kontynuowaniem zapoznaj się z tymi materiałami.
Token dostępu to długi ciąg znaków o losowym wyglądzie, który umożliwia Edge weryfikowanie przychodzących żądań do interfejsu API (można go traktować jako zastępstwo typowych danych logowania – nazwy użytkownika i hasła). Technicznie token jest kluczem, który odnosi się do zbioru metadanych wyglądających tak:
{ "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" }
Metadane tokena zawierają rzeczywisty ciąg tokena dostępu, informacje o wygaśnięciu, identyfikację aplikacji dewelopera, dewelopera i usług powiązanych z tokenem. Zauważysz też, że metadane zawierają też „scope”.
Jak token uzyskuje swój zakres?
Pierwszym kluczem do zrozumienia zakresu jest pamiętanie, że każda usługa w aplikacji dewelopera może mieć przypisanych 0 lub więcej zakresów. Zakresy te można przypisać podczas tworzenia usługi lub dodać później. Istnieją one jako lista nazw i są uwzględniane w "metadanych" powiązanych z każdą usługą.
Gdy tworzysz aplikację dewelopera i dodajesz do niej usługi, Edge sprawdza wszystkie usługi w aplikacji dewelopera i tworzy listę wszystkich zakresów tych usług (główną lub globalną listę zakresów aplikacji – sumę wszystkich rozpoznanych zakresów).
Gdy aplikacja kliencka prosi o token dostępu w Apigee Edge, może opcjonalnie określić, jakie zakresy mają być powiązane z tym tokenem. Na przykład to żądanie prosi o zakres "A". Oznacza to, że klient prosi serwer autoryzacji (Edge) o wygenerowanie tokena dostępu z zakresem "A" (dającym aplikacji uprawnienia do wywoływania interfejsów API, które mają zakres "A"). Aplikacja wysyła żądanie POST w ten sposób:
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
Co się dzieje
Gdy Edge otrzyma to żądanie, wie, która aplikacja je wysyła, i wie, w której
aplikacji dewelopera zarejestrował się klient (identyfikator klienta i klucz tajny klienta są zakodowane w nagłówku uwierzytelniania podstawowego). Ponieważ uwzględniony jest parametr zapytania scope, Edge musi
sprawdzić, czy któraś z usług interfejsu API powiązanych z aplikacją dewelopera ma zakres "A". Jeśli tak,
generowany jest token dostępu z zakresem "A". Można na to również spojzeć w taki sposób, że parametr zapytania scope
jest rodzajem filtra. Jeśli aplikacja dewelopera rozpoznaje zakresy "A, B, X", a parametr zapytania określa "scope=X Y Z", do tokena zostanie przypisany tylko zakres "X".
Co się stanie, jeśli klient nie dołączy parametru scope? W takim przypadku Edge generuje token , który zawiera wszystkie zakresy rozpoznawane przez aplikację dewelopera. Należy pamiętać, że domyślnym działaniem jest zwracanie tokena dostępu, który zawiera sumę wszystkich zakresów wszystkich usług uwzględnionych w aplikacji dewelopera.
Jeśli żadna z usług powiązanych z aplikacją dewelopera nie określa zakresów, a token ma zakres, wywołania wykonane za pomocą tego tokena nie powiodą się.
Załóżmy, że aplikacja dewelopera rozpoznaje te zakresy: A B C D. Jest to główna lista zakresów aplikacji. Może się zdarzyć, że jedna usługa w aplikacji ma zakres A i B, a druga ma zakres C
i D lub dowolną kombinację. Jeśli klient nie określi parametru scope (lub jeśli
określi parametr scope bez wartości), token otrzyma wszystkie 4 zakresy: A, B, C,
i D. Token otrzymuje zestaw zakresów, który jest sumą wszystkich zakresów rozpoznawanych
przez aplikację dewelopera.
Istnieje jeszcze jeden przypadek, w którym domyślnym działaniem jest zwracanie tokena dostępu ze wszystkimi rozpoznanymi zakresami. Dzieje się tak, gdy zasada GenerateAccessToken (zasada Apigee Edge, która generuje tokeny dostępu) nie określa elementu <Scope>.
Oto na przykład zasada GenerateAccessToken, w której <Scope>
określono. Jeśli element <Scope> jest pominięty (lub jeśli jest
obecny, ale pusty), wykonywane jest działanie domyślne.
<?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>
Jak wymuszane są zakresy?
Pamiętaj, że w Apigee Edge tokeny dostępu są weryfikowane za pomocą zasady OAuthV2 (zwykle umieszczanej na samym początku przepływu proxy). Zasada musi mieć określoną operację VerifyAccessToken. Przyjrzyjmy się tej zasadzie:
<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>Zwróć uwagę na element <Scope>. Służy on do określania, które zakresy będą akceptowane przez zasadę.
W tym przykładzie zasada zostanie spełniona tylko wtedy, gdy token dostępu zawiera zakres „A”. Jeśli ten element <Scope> jest pominięty lub nie ma wartości, zasada ignoruje zakres tokena dostępu.
Teraz, dzięki możliwości weryfikowania tokenów dostępu na podstawie zakresu, możesz projektować interfejsy API tak, aby wymuszały określone zakresy. Możesz to zrobić, projektując niestandardowe przepływy z dołączonymi do nich zasadami VerifyAccessToken , które uwzględniają zakres.
Załóżmy, że Twój interfejs API ma przepływ zdefiniowany dla punktu końcowego /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>Gdy ten przepływ zostanie uruchomiony (przyjdzie żądanie z /resourceA w sufiksie ścieżki
), natychmiast zostanie wywołana zasada OAuthV2-VerifyAccessTokenA. Ta zasada sprawdza, czy
token dostępu jest prawidłowy, i sprawdza, jakie zakresy obsługuje token. Jeśli zasada jest
skonfigurowana tak jak w przykładzie poniżej, z elementem <Scope>A</Scope>, zasada zostanie spełniona tylko wtedy,
gdy token dostępu ma zakres "A". W przeciwnym razie zwróci błąd.
<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>Podsumowując, deweloperzy interfejsów API są odpowiedzialni za projektowanie wymuszania zakresów w swoich interfejsach API. Aby to zrobić, tworzą niestandardowe przepływy do obsługi określonych zakresów i dołączają zasady VerifyAccessToken , aby wymuszać te zakresy.
Przykłady kodu
Na koniec przyjrzyjmy się kilku przykładowym wywołaniom interfejsu API, które pomogą zilustrować, jak tokeny otrzymują zakresy i jak są one wymuszane.
Przypadek domyślny
Załóżmy, że masz aplikację dewelopera z usługami, a suma zakresów tych usług to: A, B i C. To wywołanie interfejsu API prosi o token dostępu, ale nie określa parametru zapytania scope.
curl -X POST -H content-type:application/x-www-form-urlencoded http://wwitman-test.apigee.net/scopecheck1/token?grant_type=client_credentials
W takim przypadku wygenerowany token otrzyma zakresy A, B i C (działanie domyślne). Metadane tokena będą wyglądać mniej więcej tak:
{ "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" }
Załóżmy teraz, że masz punkt końcowy interfejsu API, który ma zakres „A” (czyli jego VerifyAccessToken wymaga zakresu „A”). Oto zasada 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>Oto przykładowe wywołanie punktu końcowego, który wymusza zakres A:
curl -X GET -H Authorization: Bearer MveXpj4UYXol38thNoJYIa8fBGlI http://wwitman-test.apigee.net/scopecheck1/resourceA
To wywołanie GET się powiedzie:
{
"hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
}Powiodło się, ponieważ zasada VerifyAccessToken, która jest uruchamiana po wywołaniu punktu końcowego, wymaga zakresu A, a token dostępu otrzymał zakresy A, B i C – działanie domyślne.
Przypadek filtrowania
Załóżmy, że masz aplikację dewelopera z usługami, które mają zakresy A, B, C i X. Prosisz o token dostępu i dołączasz parametr zapytania scope w ten sposób:
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'
W takim przypadku wygenerowany token otrzyma zakresy A i X, ponieważ zarówno A, jak i X są a prawidłowymi zakresami. Pamiętaj, że aplikacja dewelopera rozpoznaje zakresy A, B, C i X. W tym przypadku, filtrujesz listę usług interfejsu API na podstawie tych zakresów. Jeśli usługa ma zakres A lub X, możesz skonfigurować punkty końcowe interfejsu API, które będą wymuszać te zakresy. Jeśli usługa nie ma zakresu A ani X (założymy, że ma zakresy B, C i Z), nie można wywoływać interfejsów API, które wymuszają zakresy A lub X, za pomocą tego tokena.
Gdy wywołasz interfejs API za pomocą nowego tokena:
curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG http://wwitman-test.apigee.net/scopecheck1/resourceX
Token dostępu jest weryfikowany przez proxy interfejsu API. Na przykład:
<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>Wywołanie GET się powiedzie i zwróci odpowiedź. Na przykład:
{
"hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
}
Powiodło się, ponieważ zasada VerifyAccessToken wymaga zakresu A lub X, a token dostępu
zawiera zakresy A i X. Oczywiście, jeśli element <Scope> byłby ustawiony na "B",
to wywołanie nie powiodłoby się.
Podsumowanie
Ważne jest, aby zrozumieć, jak Apigee Edge obsługuje zakresy OAuth 2.0. Oto najważniejsze informacje:
- Aplikacja dewelopera „rozpoznaje” sumę wszystkich zakresów zdefiniowanych dla wszystkich jej usług.
- Gdy aplikacja prosi o token dostępu, może określić, jakie zakresy ma mieć. Apigee Edge (serwer autoryzacji) musi określić, które zakresy faktycznie przypisze do tokena dostępu na podstawie (a) żądanych zakresów i (b) zakresów rozpoznawanych przez aplikację dewelopera.
- Jeśli Apigee Edge nie jest skonfigurowany do sprawdzania zakresu (element
<Scope>jest pominięty w zasadzie VerifyAccessToken lub jest pusty), wywołanie interfejsu API powiedzie się, o ile zakres osadzony w tokenie dostępu pasuje do jednego z zakresów rozpoznawanych przez zarejestrowaną aplikację dewelopera (jednego z zakresów na „głównej” liście zakresów aplikacji). - Jeśli token dostępu nie ma powiązanych z nim zakresów, powiedzie się tylko
w przypadkach, gdy Edge nie uwzględnia zakresu (element
<Scope>jest pominięty w zasadzie VerifyAccessToken lub jest pusty).