이 페이지는 Apigee 및 Apigee Hybrid에 적용됩니다.
Apigee Edge 문서 보기
이 주제에서는 Apigee로 OAuth 2.0 범위를 사용하고 적용하는 방법을 설명합니다.
OAuth2 범위란 무엇인가요?
OAuth 2.0 범위를 사용하면 액세스 토큰에 부여된 액세스 양을 제한할 수 있습니다. 예를 들어 클라이언트 앱에 발급된 액세스 토큰에는 보호된 리소스에 대한 READ 및 WRITE 액세스 권한 또는 READ 액세스 권한만 부여될 수 있습니다. API를 구현하여 원하는 모든 범위 또는 범위 조합을 적용할 수 있습니다. 따라서 클라이언트가 READ 범위를 가진 토큰을 받아 WRITE 액세스를 필요로 하는 API 엔드포인트를 호출하려고 시도하면 호출이 실패합니다.
이 주제에서는 액세스 토큰에 범위가 할당되는 방법과 Apigee가 OAuth 2.0 범위를 적용하는 방법을 설명합니다. 이 주제를 읽은 후에는 안심하고 범위를 사용할 수 있습니다.
액세스 토큰에 범위가 어떻게 할당되나요?
Apigee가 액세스 토큰을 생성하면 해당 토큰에 범위를 할당할 수 있습니다. 이러한 과정을 이해하려면 먼저 API 제품, 개발자, 개발자 앱과 같은 Apigee 항목에 대해 잘 알고 있어야 합니다. 소개는 게시 소개를 참조하세요. 계속하기 전에 이 자료를 검토하는 것이 좋습니다.
액세스 토큰은 Apigee가 수신되는 API 요청을 확인할 수 있도록 하는 무작위 형식의 긴 문자열입니다(일반적으로 사용자 이름/비밀번호 사용자 인증 정보의 역할). 기술적으로 이 토큰은 다음과 같은 메타데이터 모음을 참조하는 키입니다.
{ "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" }
토큰의 메타데이터에는 실제 액세스 토큰 문자열, 만료 정보, 개발자 앱 식별, 개발자, 토큰과 관련된 제품이 포함됩니다. 메타데이터에는 '범위'도 포함됩니다.
토큰은 범위를 어떻게 가져오나요?
범위를 이해하는 첫 번째 핵심은 개발자 앱의 각 제품에 0개 이상의 범위가 할당할 수 있다는 점입니다. 이러한 범위는 제품이 생성될 때 할당되거나 나중에 추가될 수 있습니다. 이러한 범위는 이름 목록으로 존재하며 각 제품과 연결된 '메타데이터'에 포함됩니다.
개발자 앱을 만들고 여기에 제품을 추가하면 Apigee는 개발자 앱의 모든 제품을 확인하고 해당 제품의 모든 범위 목록(모든 인식된 범위의 통합인 앱의 마스터 또는 전역 범위 목록)을 만듭니다.
클라이언트 앱이 Apigee에서 액세스 토큰을 요청하는 경우 선택적으로 해당 토큰과 연결할 범위를 지정할 수 있습니다. 예를 들어 다음 요청에서는 'A' 범위를 요청합니다. 즉, 클라이언트는 'A' 범위를 가진 API를 호출할 수 있는 권한을 앱에 부여하여 승인 서버(Apigee)가 'A' 범위를 가진 액세스 토큰을 생성하도록 요청합니다. 앱은 다음과 같이 POST 요청을 전송합니다.
curl -i -X POST -H Authorization: Basic Mg12YTk2UkEIyIBCrtro1QpIG \ -H content-type:application/x-www-form-urlencoded \ https://apitest.acme.com/oauth/token?grant_type=client_credentials&scope=A
변경사항
Apigee가 이 요청을 받으면 Edge는 어떤 앱이 요청을 보내는지, 어떤 개발자 앱이 클라이언트에 등록되었는지 파악합니다(클라이언트 ID와 클라이언트 보안 비밀번호 키는 기본 인증 헤더에 인코딩되어 있음). scope
쿼리 매개변수가 포함되어 있으므로 Apigee는 개발자 앱과 연결된 API 제품 중 어느 제품이라도 'A'의 범위를 가지는지 결정해야 합니다. 그렇게 하면 'A' 범위의 액세스 토큰이 생성됩니다. 또 다른 관점으로 조회 범위 쿼리 매개변수를 일종의 필터로 볼 수 있습니다. 개발자 앱이 범위 'A, B, X'를 인식하고 쿼리 매개변수가 'scope=X Y Z'를 지정하면 범위 'X'만 토큰에 할당됩니다.
클라이언트가 범위 매개변수를 연결하지 않는다고 가정해 보겠습니다. 이 경우 Apigee는 개발자 앱에서 인식하는 모든 범위를 포함하는 토큰을 생성합니다. 기본 동작은 개발자 앱에 포함된 모든 제품의 모든 범위 통합이 포함된 액세스 토큰을 반환하는 것입니다.
개발자 앱과 연결된 제품이 범위를 지정하지 않고 토큰에 범위가 있다면 이 토큰으로 수행된 호출은 실패합니다.
개발자 앱이 A, B, C, D의 범위를 인식한다고 가정해 보겠습니다. 이는 앱의 마스터 범위 목록입니다. 앱의 제품 하나에는 범위 A와 B가 있고 다른 하나에는 범위 C와 D 또는 이 모든 조합이 있을 수 있습니다. 클라이언트가 scope
매개변수를 지정하지 않거나 값이 없는 범위 매개변수를 지정하면 토큰에는 A, B, C, D의 4가지 범위가 모두 부여됩니다. 다시 말해 이 토큰은 개발자 앱이 인식하는 모든 범위의 통합인 범위 집합을 수신합니다.
모든 인식된 범위가 포함된 액세스 토큰을 반환하는 것이 기본 동작인 경우도 있습니다. 이는 GenerateAccessToken 정책(액세스 토큰을 생성하는 Apigee 정책)이 <Scope>
요소를 지정하지 않는 경우입니다.
예를 들어 <Scope>
가 지정된 GenerateAccessToken 정책은 다음과 같습니다. <Scope>
요소가 없으면(또는 존재하지만 비어 있는 경우) 기본 동작이 실행됩니다.
<?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>
범위는 어떻게 적용되나요?
먼저 Apigee에서 액세스 토큰은 OAuthV2 정책(일반적으로 프록시 흐름의 맨 처음에 배치됨)으로 검증됩니다. 정책에는 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> <!-- Optional: space-separated list of scope names. --> <GenerateResponse enabled="true"/> </OAuthV2>
<Scope>
요소를 확인합니다. 이는 정책이 허용할 범위를 지정하는 데 사용됩니다.
이 예시에서는 액세스 토큰에 범위 'A'가 포함된 경우에만 정책이 성공합니다. 이 <Scope> 요소를 생략하거나 값이 없는 경우 정책은 액세스 토큰의 범위를 무시합니다.
이제 범위 기준의 액세스 토큰 검증을 통해 특정 범위를 적용하도록 API를 설계할 수 있습니다. 이를 위해 범위 인식 VerifyAccessToken 정책이 연결된 커스텀 흐름을 설계합니다.
API에 /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>
이 흐름이 트리거되면(경로 서픽스에 /resourceA
가 포함된 요청 수신) OAuthV2-VerifyAccessTokenA 정책이 즉시 호출됩니다. 이 정책은 액세스 토큰이 유효한지 확인하고 토큰이 지원하는 범위를 확인합니다. 아래 예시와 같이 <Scope>A</Scope>로 정책이 구성되면 액세스 토큰이 'A' 범위를 가진 경우에만 정책이 성공합니다. 그렇지 않으면 오류가 반환됩니다.
<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>
요약하자면 API 개발자는 API에 범위 적용을 설계해야 합니다. 이를 위해 개발자는 특정 범위를 처리하는 커스텀 흐름을 만들고 VerifyAccessToken 정책을 연결하여 이러한 범위를 적용합니다.
코드 예
마지막으로, 토큰이 범위를 수신하는 방식과 범위가 적용되는 방식의 설명을 위해 API 호출의 예시를 살펴보겠습니다.
기본 사례
제품과 함께 개발자 앱이 있고 해당 제품 범위의 통합이 A, B, C라고 가정해 보겠습니다. 이 API 호출은 액세스 토큰을 요청하지만 범위 쿼리 매개변수를 지정하지 않습니다.
curl -X POST -H content-type:application/x-www-form-urlencoded \ https://apitest.acme.com/scopecheck1/token?grant_type=client_credentials
이 경우 생성된 토큰에는 A, B, C 범위가 지정됩니다(기본 동작). 토큰의 메타데이터는 다음과 같습니다.
{ "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" }
'A' 범위를 가진 API 엔드포인트가 있다고 가정해 보겠습니다(즉, 'A' 범위를 필요로 하는 VerifyAccessToken). 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>
다음은 샘플 호출과 범위 A를 적용하는 엔드포인트입니다.
curl -X GET -H Authorization: Bearer MveXpj4UYXol38thNoJYIa8fBGlI \ https://apitest.acme.com/scopecheck1/resourceA
이 GET 호출이 성공합니다.
{ "hello" : "Tue, 25 Nov 2014 01:35:53 UTC" }
이는 엔드포인트를 호출할 때 트리거되는 VerifyAccessToken 정책에 범위 A를 필요로 하고 기본 동작으로 액세스 토큰에 A, B, C 범위가 부여되었기 때문입니다.
필터링 사례
범위 A, B, C, X를 가지는 제품과 함께 개발자 앱이 있다고 가정해 보겠습니다. 다음과 같이 액세스 토큰을 요청하고 scope
쿼리 매개변수를 포함합니다.
curl -i -X POST -H content-type:application/x-www-form-urlencoded \ 'https://apitest.acme.com/oauth/token?grant_type=client_credentials&scope=A X'
이 경우 A와 X가 모두 유효한 범위이므로 생성된 토큰에는 A 및 X 범위가 지정됩니다. 개발자 앱은 범위 A, B, C, X를 인식함을 기억하세요. 여기에서는 이러한 범위를 기준으로 API 제품 목록을 필터링합니다. 제품에 A 또는 X 범위가 있는 경우 이러한 범위를 적용하도록 API 엔드포인트를 구성할 수 있습니다. 제품에 범위 A 또는 X가 없는 경우(B, C, Z가 있다고 가정) A 또는 X 범위를 적용하는 API를 토큰으로 호출할 수 없습니다.
새 토큰으로 API를 호출하는 경우 다음 명령어를 사용합니다.
curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG \ https://apitest.acme.com/scopecheck1/resourceX
액세스 토큰은 API 프록시에서 검증됩니다. 예를 들면 다음과 같습니다.
<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>
GET 호출 트리거가 성공하고 응답을 반환합니다. 예를 들면 다음과 같습니다.
{ "hello" : "Tue, 25 Nov 2014 01:35:53 UTC" }
이는 VerifyAccessToken 정책에 범위 A 또는 X가 필요로 하고 액세스 토큰에 범위 A와 X가 포함되어 있기 때문입니다. 물론, <Scope>
요소가 'B'로 설정된 경우 이 호출은 실패합니다.
요약
Apigee가 OAuth 2.0 범위를 처리하는 방식을 이해하는 것이 중요합니다. 핵심 요점은 다음과 같습니다.
- 개발자 앱이 모든 제품에 정의된 모든 범위의 통합을 '인식'합니다.
- 앱은 액세스 토큰을 요청할 때 원하는 범위를 지정할 수 있습니다. (a) 요청된 범위 및 (b) 개발자 앱에서 인식되는 범위를 기반으로 실제로 액세스 토큰에 할당할 범위를 확인하는 것은 Apigee(승인 서버)의 담당입니다.
- Apigee가 범위를 확인하도록 구성되지 않은 경우(
<Scope>
요소가 VerifyAccessToken 정책에 누락되었거나 비어 있는 경우) 액세스 토큰에 삽입된 범위와 등록된 개발자 앱에서 인식된 범위(앱의 '마스터' 범위 목록 중 하나의 범위)가 일치하기만 하면 API 호출은 성공합니다. - 액세스 토큰에 연결된 범위가 없으면 Apigee가 범위를 고려하지 않는 경우에만 성공합니다(
<Scope>
요소가 VerifyAccessToken 정책에서 누락되었거나 비어 있는 경우).