OAuth로 API 보호

이 가이드에서는 다음 작업을 수행하는 방법을 설명합니다.

  • 샘플 API 프록시를 다운로드하고 배포합니다.
  • OAuth로 보호되는 API 프록시를 만듭니다.
  • 제품, 개발자, 앱을 만듭니다.
  • OAuth 액세스 토큰에 대한 사용자 인증 정보를 교환합니다.
  • 액세스 토큰으로 API를 호출합니다.

OAuth는 사용자가 사용자 이름과 비밀번호를 증명하지 않아도 앱에서 사용자를 대신해 정보에 액세스할 수 있게 해주는 승인 프로토콜입니다.

OAuth를 사용하면 보안 사용자 인증 정보(사용자 이름/비밀번호 또는 키/보안 비밀)가 액세스 토큰으로 교환됩니다. 예를 들면 다음과 같습니다.

joe:joes_password(사용자 이름:비밀 번호) 또는
Nf2moHOASMJeUmXVdDhlMbPaXm2U7eMc:unUOXYpPe74ZfLEb(키:보안 비밀)

다음으로 교환됩니다.

b0uiYwjRZLEo4lEu7ky2GGxHkanN

액세스 토큰은 임의 문자열이며 일시적이므로(상대적으로 짧은 시간 후 만료) 앱 워크플로에서 사용자를 인증할 때 배포하면 실제 사용자 인증 정보를 배포하는 것보다 훨씬 더 안전합니다.

OAuth 2.0 사양은 앱에 대한 액세스 토큰을 배포하기 위해 '부여 유형'이라는 여러 메커니즘을 정의합니다. OAuth 2.0에서 정의하는 권한 부여 유형을 '클라이언트 사용자 인증 정보'라고 합니다. 이 부여 유형에서는 위 예시처럼 고객 키/고객 보안 비밀 쌍인 클라이언트 사용자 인증 정보 대신 OAuth 액세스 토큰이 생성됩니다.

Apigee의 클라이언트 사용자 인증 정보 부여 유형은 API 프록시의 정책을 통해 구현됩니다. 일반적인 OAuth 흐름에는 다음 두 단계가 포함됩니다.

  • API 프록시 1을 호출하여 클라이언트 사용자 인증 정보에서 OAuth 액세스 토큰을 생성합니다. API 프록시의 OAuth v2.0 정책에서 이를 처리합니다.
  • API 프록시 2를 호출하여 API 호출에서 OAuth 액세스 토큰을 전송합니다. API 프록시는 OAuth v2.0 정책을 사용하여 액세스 토큰을 확인합니다.

토큰 생성 API 프록시 다운로드 및 배포

이 단계에서는 API 호출로 전송되는 고객 키와 고객 비밀번호에서 OAuth 액세스 토큰을 생성하는 API 프록시를 만듭니다. Apigee는 이를 수행하는 샘플 API 프록시를 제공합니다. 지금 프록시를 다운로드하고 배포한 후 나중에 가이드에서 사용합니다. 이 API 프록시를 직접 쉽게 빌드할 수 있습니다. 이 다운로드 및 배포 단계는 편의를 위해 제작되었으며 이미 생성된 프록시를 얼마나 쉽게 공유할 수 있는지 보여줍니다.

  1. 파일 시스템의 디렉터리에 'oauth' 샘플 API 프록시 ZIP 파일을 다운로드합니다.
  2. Apigee UI로 이동하고 로그인합니다.
  3. 왼쪽 탐색 메뉴에서 개발 > API 프록시를 선택합니다.
  4. + Proxy를 클릭합니다.
    프록시 만들기 버튼
  5. 프록시 만들기 마법사에서 프록시 번들 업로드를 선택합니다.
  6. 다운로드한 oauth.zip 파일을 선택하고 Next를 클릭합니다.
  7. 만들기를 클릭합니다.
  8. 빌드가 완료되면 프록시 편집을 클릭하여 API 프록시 편집기에서 새 프록시를 봅니다.
  9. 버전 드롭다운을 클릭하고 프록시를 배포할 버전 번호를 선택합니다.

액세스 토큰 생성 API 프록시를 성공적으로 다운로드하고 Edge 조직에 배포했습니다.

OAuth 흐름 및 정책 보기

API 프록시에 포함된 항목을 자세히 살펴보겠습니다.

  1. API 프록시 편집기에서 Develop 탭을 클릭합니다. 왼쪽 Navigator 창에 두 개의 정책이 표시됩니다. Proxy Endpoints 섹션에 2개의 POST 흐름도 표시됩니다.
  2. Proxy Endpoints에서 AccessTokenClientCredential을 클릭합니다.

    XML 코드 보기에는 AccessTokenClientCredential이라는 Flow가 표시됩니다.

    <Flow name="AccessTokenClientCredential">
        <Description/>
        <Request>
            <Step>
                <Name>GenerateAccessTokenClient</Name>
            </Step>
        </Request>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/accesstoken") and (request.verb = "POST")</Condition>
    </Flow>
    

    흐름은 API 프록시의 처리 단계입니다. 이 경우 특정 조건이 충족되면 흐름이 트리거됩니다('조건부 흐름'이라고 함). <Condition> 요소에 정의된 조건은 /accesstoken 리소스에 API 프록시를 요청하고 요청 동사가 POST인 경우 액세스 토큰을 생성하는 GenerateAccessTokenClient 정책을 실행함을 나타냅니다.

  3. 이제 조건부 흐름이 트리거하는 정책을 살펴보겠습니다. 흐름도에서 GenerateAccessTokenClient 정책 아이콘을 클릭합니다.

    다음 XML 구성이 코드 보기에 로드됩니다.

    <OAuthV2 name="GenerateAccessTokenClient">
        <!-- This policy generates an OAuth 2.0 access token using the client_credentials grant type -->
        <Operation>GenerateAccessToken</Operation>
        <!-- This is in milliseconds, so expire in an hour -->
        <ExpiresIn>3600000</ExpiresIn>
        <SupportedGrantTypes>
            <!-- This part is very important: most real OAuth 2.0 apps will want to use other
             grant types. In this case it is important to NOT include the "client_credentials"
             type because it allows a client to get access to a token with no user authentication -->
            <GrantType>client_credentials</GrantType>
        </SupportedGrantTypes>
        <GrantType>request.queryparam.grant_type</GrantType>
        <GenerateResponse/>
    </OAuthV2>
    

    구성에는 다음이 포함됩니다.

    • <Operation> - 사전 정의된 여러 값 중 하나일 수 있으며 정책이 수행할 작업을 정의합니다. 이 경우 액세스 토큰을 생성합니다.
    • 토큰은 생성 후 1시간(3,600,000밀리초) 후에 만료됩니다.
    • <SupportedGrantTypes>에서 사용되는 OAuth <GrantType>client_credentials입니다(고객 키와 보안 비밀을 OAuth 토큰으로 교환).
    • 두 번째 <GrantType> 요소는 OAuth 2.0 사양의 요구사항에 따라 API 호출에서 부여 유형 매개변수를 확인할 위치를 정책에 알립니다. 나중에 API 호출에서 확인할 수 있습니다. 또한 부여 유형은 HTTP 헤더(request.header.grant_type)에 또는 양식 매개변수(request.formparam.grant_type)로 전송될 수 있습니다.

현재는 API 프록시를 사용하여 다른 작업을 수행할 필요가 없습니다. 이후 단계에서 이 API 프록시를 사용하여 OAuth 액세스 토큰을 생성합니다. 하지만 먼저 몇 가지 작업을 수행해야 합니다.

  • 실제로 OAuth로 보호하려는 API 프록시를 만듭니다.
  • 액세스 토큰으로 교환해야 하는 고객 키와 고객 보안 비밀을 생성하는 몇 가지 아티팩트를 추가로 만듭니다.

OAuth로 보호되는 API 프록시 만들기

이제 보호하려는 API 프록시를 만듭니다. 이 프록시는 원하는 내용을 반환하는 API 호출입니다. 이 경우 API 프록시는 Apigee의 mocktarget 서비스를 호출하여 IP 주소를 반환합니다. 하지만 API 호출로 유효한 OAuth 액세스 토큰을 전달한 경우에만 확인할 수 있습니다.

여기서 만든 API 프록시에는 요청의 OAuth 토큰을 확인하는 정책이 포함됩니다.

  1. 왼쪽 탐색 메뉴에서 개발 > API 프록시를 선택합니다.
  2. + Proxy를 클릭합니다.
    프록시 만들기 버튼
  3. 프록시 빌드 마법사에서 역방향 프록시(가장 일반적)를 선택합니다.
  4. 다음 방법으로 프록시를 구성합니다.
    필드 작업
    Proxy Name helloworld_oauth2 입력
    Project Base Path

    /hellooauth2로 변경

    Project Base Path는 API 프록시에 요청을 보내는 데 사용되는 URL의 일부입니다.

    Existing API

    https://mocktarget.apigee.net/ip 입력

    이는 Apigee가 API 프록시에 대한 요청에서 호출하는 대상 URL을 정의합니다.

    설명 hello world protected by OAuth 입력
  5. 다음을 클릭합니다.
  6. 일반적인 정책 페이지에서 다음을 수행합니다.
    필드 작업
    보안: 승인 선택:
    • OAuth 2.0

    이러한 옵션은 매우 편리합니다. API 프록시에 정책 두 개가 자동으로 추가되고 API 제품이 생성됩니다.

  7. 다음을 클릭합니다.
  8. 요약 페이지의 선택적 배포에서 환경을 선택하고 만들기를 클릭합니다.
  9. 프록시 편집을 클릭하여 API 프록시의 개요 페이지를 표시합니다.
    API 프록시가 자동으로 배포됩니다. 배포가 완료되는 데 잠시 시간이 걸릴 수 있습니다.

정책 보기

지금까지 만든 항목을 자세히 살펴보겠습니다.

  1. API 프록시 편집기에서 Develop 탭을 클릭합니다. API 프록시의 요청 흐름에 2개의 정책이 추가된 것을 볼 수 있습니다.
    • Verify OAuth v2.0 Access Token – API 호출에 유효한 OAuth 토큰이 있는지 확인합니다.
    • Remove Header Authorization – 확인된 액세스 토큰이 대상 서비스로 전달되지 않도록 삭제하는 Assign Message 정책. (대상 서비스에 OAuth 액세스 토큰이 필요한 경우에는 이 정책을 사용하지 않습니다).
  2. 흐름 뷰에서 Verify OAuth v2.0 Access Token 아이콘을 클릭하고 코드 창에서 아래의 XML을 확인합니다.

    <OAuthV2 async="false" continueOnError="false" enabled="true" name="verify-oauth-v2-access-token">
        <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
        <Operation>VerifyAccessToken</Operation>
    </OAuthV2>
    

    <Operation>VerifyAccessToken입니다. Operation은 정책이 수행해야 하는 작업을 정의합니다. 이 경우 요청에서 유효한 OAuth 토큰을 확인합니다.

API 제품 추가

Apigee UI를 사용하여 API 제품을 추가하려면 다음 안내를 따르세요.

  1. 게시 > API 제품을 선택합니다.
  2. +API 제품을 클릭합니다.
  3. API 제품의 제품 세부정보를 입력합니다.
    필드 설명
    이름 API 제품의 내부 이름입니다. 이름에 특수문자를 지정하지 마세요.
    참고: API 제품이 생성된 후에는 이름을 수정할 수 없습니다.
    표시 이름 API 제품의 표시 이름입니다. 표시 이름은 UI에서 사용되며 언제든지 수정할 수 있습니다. 지정되지 않으면 이름 값이 사용됩니다. 이 필드는 이름 값을 사용하여 자동으로 채워지며 해당 콘텐츠를 수정하거나 삭제할 수 있습니다. 표시 이름에는 특수문자가 포함될 수 있습니다.
    설명 API 제품에 대한 설명입니다.
    환경 API 제품이 액세스를 허용할 환경입니다. API 프록시를 배포한 환경을 선택합니다.
    액세스 공개를 선택합니다.
    액세스 요청 자동 승인 모든 앱에서 이 API 제품의 주요 요청을 자동으로 승인합니다.
    할당량 이 가이드에서는 무시합니다.
    허용된 OAuth 범위 이 가이드에서는 무시합니다.
  4. API 리소스 섹션에서 방금 만든 API 프록시를 추가합니다.
  5. 경로 섹션에서 경로 '/'를 추가합니다.
  6. 저장을 클릭합니다.

조직에 개발자와 앱 추가

이제 API를 사용하도록 개발자 가입 워크플로를 시뮬레이션합니다. 개발자가 개발자 포털을 통해 자신과 자신의 앱을 등록하는 것이 가장 좋습니다. 하지만 이 단계에서는 개발자와 앱을 관리자로 추가합니다.

개발자는 하나 이상의 앱으로 API를 호출하며 각 앱은 고유한 고객 키와 고객 보안 비밀을 발급받습니다. 또한 Apigee는 OAuth 토큰에 속한 개발자와 앱을 알고 있으므로 이 앱별 키/보안 비밀은 개발자, API 제공업체에게 API 액세스에 대한 더 세부적인 제어 권한과 API 트래픽에 대한 더 세분화된 분석 보고 기능을 제공합니다.

개발자 만들기

Nigel Tufnel이라는 이름의 개발자를 만들어 보겠습니다.

  1. 메뉴에서 Publish > Developers를 선택합니다.
  2. + Developer를 클릭합니다.
  3. 새 Developer 창에 다음을 입력합니다.
    필드 입력
    First Name Nigel
    Last Name Tufnel
    Username nigel
    Email nigel@example.com
  4. Save를 클릭합니다.

앱 등록

Nigel의 앱을 만들어 보겠습니다.

  1. Publish > Apps를 선택합니다.
  2. + App을 클릭합니다.
  3. New App 창에 다음을 입력합니다.
    필드 작업
    NameDisplay Name nigel_app 입력
    Developer Developer를 클릭하고 Nigel Tufnel (nigel@example.com)을 선택합니다.
    Callback URLNotes 비워 두기
  4. Products에서 Add Product를 클릭합니다.
  5. 방금 만든 API 제품을 추가합니다.
  6. 만들기를 클릭합니다.

고객 키 및 고객 보안 비밀 받기

이제 OAuth 액세스 토큰으로 교환될 고객 키와 고객 보안 비밀을 가져올 수 있습니다.

  1. nigel_app 페이지가 표시되는지 확인합니다. 그렇지 않으면 앱 페이지(게시 > 앱)에서 nigel_app을 클릭합니다.
  2. nigel_app 페이지의 KeySecret 열에서 Show를 클릭합니다. 키/보안 비밀이 이전에 만든 API 제품과 연결됩니다.

  3. Key와 Secret을 선택하고 복사합니다. Paste them in a temporary text file을 선택합니다. 이후 단계에서 이를 사용하여 이러한 사용자 인증 정보를 OAuth 액세스 토큰으로 교환할 API 프록시를 호출합니다.

API를 호출하여 IP 주소 가져오기(실패!)

방금 만든 보호된 API 프록시를 호출해 보세요. 호출에 OAuth 액세스 토큰을 전달하지 않습니다.

curl -v -k https://EXTERNAL_IP/hellooauth2

여기서 EXTERNAL_IP는 Apigee가 설치될 때 정의된 인터넷 연결 IP 주소의 주소입니다. 라우팅 구성을 참조하세요.

API 프록시에는 요청에서 유효한 OAuth 토큰을 확인하는 Verify OAuth v2.0 Access Token 정책이 있으므로 호출이 다음 메시지와 함께 실패합니다.

{"fault":{"faultstring":"Invalid access token","detail":{"errorcode":"oauth.v2.InvalidAccessToken"}}}

이 경우 실패하는 것이 좋습니다. 즉, API 프록시가 훨씬 더 안전하다는 의미입니다. 유효한 OAuth 액세스 토큰이 있는 신뢰할 수 있는 앱만 이 API를 성공적으로 호출할 수 있습니다.

OAuth 액세스 토큰 받기

그런 다음 키와 보안 비밀을 복사하여 텍스트 파일에 붙여넣고 OAuth 액세스 토큰과 교환합니다. 이제 가져온 API 샘플 프록시인 oauth에 대해 API를 호출합니다. 그러면 API 액세스 토큰이 생성됩니다.

이 키와 보안 비밀을 사용하여 다음 cURL을 호출합니다(프로토콜은 https).

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
"https://EXTERNAL_IP/oauth/client_credential/accesstoken?grant_type=client_credentials" \
-d "client_id={key}&client_secret={secret}"

Postman 같은 클라이언트를 사용하여 호출하는 경우 client_idclient_secret는 요청 본문에 들어가고 x-www-form-urlencoded여야 합니다.

다음과 같은 응답이 표시됩니다.

{
  "issued_at" : "1466025769306",
  "application_name" : "716bbe61-f14a-4d85-9b56-a62ff8e0d347",
  "scope" : "",
  "status" : "approved",
  "api_product_list" : "[helloworld_oauth2-Product]",
  "expires_in" : "3599", //--in seconds
  "developer.email" : "nigel@example.com",
  "token_type" : "BearerToken",
  "client_id" : "xNnREu1DNGfiwzQZ5HUN8IAUwZSW1GZW",
  "access_token" : "GTPY9VUHCqKVMRB0cHxnmAp0RXc0",
  "organization_name" : "myOrg",
  "refresh_token_expires_in" : "0", //--in seconds
  "refresh_count" : "0"
}

OAuth 액세스 토큰을 가져왔습니다. 따옴표 없이 access_token 값을 복사하여 텍스트 파일에 붙여넣습니다. 잠시 후 사용하게 됩니다.

어떻게 된 것인가요?

이전에는 oauth 프록시에서 '조건부 흐름'을 확인할 때 리소스 URI가 /accesstoken이고 요청 동사가 POST인 경우에 액세스 토큰을 생성하는 GenerateAccessTokenClient OAuth 정책을 실행할 것인지 확인했습니다. cURL 명령어가 이러한 조건을 충족하므로 OAuth 정책이 실행되었습니다. 고객 키와 고객 보안 비밀을 확인하고 1시간 후에 만료되는 OAuth 토큰으로 교환했습니다.

액세스 토큰으로 API 호출(성공!)

이제 액세스 토큰이 있으므로 이를 사용하여 API 프록시를 호출할 수 있습니다. 다음 cURL을 호출합니다. Apigee 조직 이름과 액세스 토큰을 대체합니다(중괄호 삭제).

curl https://EXTERNAL_IP/hellooauth2 -H "Authorization: Bearer {access-token}"

이제 IP 주소를 반환하는 API 프록시를 성공적으로 호출합니다. 예를 들면 다음과 같습니다.

{"ip":"::ffff:192.168.14.136"}

API 호출을 한 시간 정도 반복할 수 있으며, 이 시간이 지나면 액세스 토큰이 만료됩니다. 한 시간 후에 호출하려면 이전 단계에 따라 새 액세스 토큰을 생성해야 합니다.

수고하셨습니다. API 프록시를 만들고 호출에 유효한 OAuth 액세스 토큰이 포함되도록 요구하여 보호했습니다.

관련 주제