타사 OAuth 토큰 사용

이 페이지는 ApigeeApigee Hybrid에 적용됩니다.

Apigee Edge 문서 보기

이 주제에서는 외부에서 생성된 액세스 토큰, 갱신 토큰, 인증 코드를 Apigee 토큰 저장소로 가져오는 방법을 설명합니다. 이 기법을 사용하여 Apigee 외부에서 생성된 토큰을 검증하도록 Apigee를 구성할 수 있습니다.

일반적인 경우 Apigee는 OAuth 토큰을 생성 및 저장하고 호출 애플리케이션으로 반환합니다. 그러면 호출 앱은 서비스를 요청할 때 해당 토큰을 Apigee에 다시 제공하고 Apigee에서 Operation = VerifyAccessToken인 OAuthV2 정책을 통해 토큰이 유효한지 확인합니다. 이 주제에서는 Apigee에서 토큰을 생성한 것처럼 토큰 확인 부분을 동일하게 유지하면서 다른 곳에서 생성된 OAuth 토큰을 저장하도록 Apigee를 구성하는 방법을 설명합니다.

이 주제에서 설명하는 기법을 보여주는 실제 예시를 보려면 Apigee에 위임된 토큰 관리 샘플을 살펴봅니다.

이것은 무엇인가요?

기존 승인 시스템이 있고 OAuth2 토큰 대신 해당 시스템에서 생성된 토큰 또는 코드 또는 Apigee에서 생성된 코드 값을 사용한다고 가정해 보겠습니다. 그런 다음 대체 토큰 또는 코드를 사용하여 보안 API 프록시 요청을 수행할 수 있으며 Apigee는 이를 Apigee에서 생성한 것처럼 검증합니다.

일부 배경

일반적인 경우 Apigee는 문자와 숫자로 이루어진 임의의 문자열을 생성하여 토큰을 생성합니다. Apigee는 토큰이 발급된 시간, 만료, 토큰이 유효한 API 제품 목록, 범위와 같은 다른 데이터를 해당 토큰에 연결합니다. 이 모든 정보는 Operation = GenerateAccessToken으로 구성된 OAuthV2 정책에 의해 자동으로 생성된 응답으로 반환될 수 있습니다. 응답은 다음과 같습니다.

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "urn://example.com/read",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "api_product_list_json": ["implicit-test"],
  "expires_in": "1799", //--in seconds
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "zBC90HhCGmGlaMBWeZAai2s3za5j",
  "organization_name": "myorg",
  "refresh_token_expires_in": "0", //--in seconds
  "refresh_count": "0"
}

access_token 값은 Apigee에서 토큰 메타데이터를 검색하는 데 사용됩니다. 예를 들어 API 프록시 요청에 Bearer 토큰 zBC90HhCGmGlaMBWeZAai2s3za5j가 포함된다고 가정해보세요. Apigee는 토큰 값을 사용하여 토큰 메타데이터를 검색하여 토큰이 유효한지 확인합니다.

여기에 설명된 단계를 따라 access_token 값이 외부 서비스에서 생성된 토큰을 저장하도록 Apigee를 구성할 수 있습니다. 예를 들어 'TOKEN-<임의의 숫자 16개>' 형식의 토큰을 생성하는 Apigee의 외부 시스템이 있다고 가정합니다. 이 경우 Apigee에서 저장하는 전체 토큰 메타데이터는 다음과 같습니다.

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "urn://example.com/read",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "api_product_list_json": ["implicit-test"],
  "expires_in": "1799", //--in seconds
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "TOKEN-1092837373654221",
  "organization_name": "myorg",
  "refresh_token_expires_in": "0", //--in seconds
  "refresh_count": "0"
}

이 경우 앱에서 API 프록시에 요청하여 Bearer 토큰 TOKEN-1092837373654221을 전달할 수 있으며 Apigee가 이를 검증할 수 있습니다. 승인 코드와 갱신 토큰에 비슷한 가져오기 패턴을 적용할 수 있습니다.

클라이언트 사용자 인증 정보 유효성 검사에 관해

토큰 생성을 위한 사전 요구사항 중 하나는 요청 클라이언트의 유효성을 검사하는 것입니다. 기본적으로 Apigee의 OAuthV2/GenerateAccessToken 정책은 암시적으로 클라이언트 사용자 인증 정보를 확인합니다. 일반적으로 OAuthV2 토큰의 요청에서 client_idclient_secret은 Authorization 헤더에 전달되고 HTTP 기본 승인(콜론 연결 뒤 base64 인코딩)을 통해 인코딩됩니다. Apigee의 OAuthV2/GenerateAccessToken 정책은 해당 헤더를 디코딩하고 client_id를 조회하고 전달된 client_secret가 해당 client_id에 유효한지 확인합니다. 이는 사용자 인증 정보가 Apigee로 알려진 경우 즉, Apigee 내에 사용자 인증 정보가 포함된 개발자 앱이 있으며, 여기에는 특정 client_idclient_secret이 포함된 경우에 작동합니다.

Apigee에서 클라이언트 사용자 인증 정보의 유효성을 검사할 수 없는 경우에는 토큰을 생성하기 전에 API 프록시를 설계하여 다른 방법을 통해 클라이언트를 명시적으로 검증해야 합니다. 이는 종종 네트워크의 원격 엔드포인트에 연결되는 ServiceCallout 정책을 통해 발생합니다.

어떤 방법이든 간에 암시적으로든 명시적으로든 토큰을 생성하는 API 프록시가 먼저 클라이언트 사용자 인증 정보를 검증해야 합니다. 클라이언트 유효성 검사는 액세스 토큰 생성과 무관합니다. Apigee를 구성하여 둘 다 수행하거나, 둘 중 하나만 수행하거나, 둘 다 수행하지 않도록 구성할 수 있습니다.

Apigee의 OAuthV2/GenerateAccessToken 정책을 사용하여 Apigee 저장소에 대한 클라이언트 사용자 인증 정보를 검증하려면 정책 구성 내에서 <ExternalAuthorization> 요소를 false로 설정하거나 완전히 생략합니다. 외부 승인 서비스를 사용하여 클라이언트 사용자 인증 정보를 명시적으로 검증하려면 <ExternalAuthorization>true로 설정합니다.

Apigee는 클라이언트 사용자 인증 정보의 유효성을 검사할 수 없지만 Apigee에서 client_id를 알고 관리할 수 있어야 합니다. Apigee의 모든 access_token은 Apigee에서 생성되었는지, 외부 시스템에서 생성된 후 Apigee로 가져왔는지와 관계없이 client_id에 표시된 클라이언트 애플리케이션과 연결되어야 합니다. 따라서 Apigee의 OAuthV2/GenerateAccessToken 정책에서 client_idclient_secret이 일치하는지 검증하지 않더라도 정책은 client_id가 유효한지, 취소되지 않았는지 확인합니다. 따라서 사전 요구사항 설정 단계에서 Apigee 관리 API를 통해 client_id를 가져와야 할 수 있습니다.

Apigee의 타사 OAuth에 대한 정책 흐름

Apigee에서 타사 OAuth 시스템의 토큰을 사용하려면 액세스 토큰을 생성하는 흐름은 다음 패턴 중 하나를 따라야 합니다.

클라이언트 사용자 인증 정보의 외부 유효성 검사

  1. ServiceCallout을 사용하여 인바운드 클라이언트 사용자 인증 정보를 확인하고 외부 토큰을 가져옵니다.
  2. ExtractVariables 또는 자바스크립트 단계를 사용하여 응답에서 외부에서 생성된 토큰을 추출합니다.
  3. AssignMessage를 사용하여 잘 알려진 특수 변수인 oauth_external_authorization_status를 설정합니다. 클라이언트 사용자 인증 정보가 유효함을 나타내려면 값이 true여야 합니다.
  4. OAuthV2/GenerateAccessToken에 <ExternalAuthorization> 요소가 true로 설정되고 <ExternalAccessToken>, <ExternalRefreshToken>, <ExternalAuthorizationCode> 중 최소 하나가 있어야 합니다.

클라이언트 사용자 인증 정보의 내부 유효성 검사

  • ServiceCallout을 사용하여 외부 토큰을 가져옵니다.
  • ExtractVariables 또는 자바스크립트 단계를 사용하여 응답에서 외부에서 생성된 토큰을 추출합니다.
  • OAuthV2/GenerateAccessToken에 <ExternalAuthorization> 요소가 false로 설정되고 <ExternalAccessToken>, <ExternalRefreshToken>, <ExternalAuthorizationCode> 중 최소 하나가 있어야 합니다.

흐름 및 정책 구성에 대한 참고사항

  • 외부 시스템을 사용하여 클라이언트 사용자 인증 정보의 유효성을 검사하려는 경우에는 필요한 작업을 수행하는 정책 흐름을 개발해야 합니다. 일반적으로 ServiceCallout 정책을 사용하여 외부에서 인식된 사용자 인증 정보를 외부 인증 서비스로 보냅니다. 외부 인증 서비스는 일반적으로 응답을 반환하고, 사용자 인증 정보가 유효하면 액세스 토큰도 반환합니다.

  • ServiceCallout 뒤에 API 프록시는 유효성 검사 상태와 외부에서 생성된 access_token 및 가능한 경우 refresh_token을 추출하기 위해 응답을 파싱해야 합니다.

  • OAuthV2/GenerateAccessToken 정책에서 <StoreToken> 요소를 true로 설정하고, <ExternalAuthorization> 요소를 true 또는 false로 적절하게 설정합니다.

    OAuthV2/GenerateAccessToken 정책이 실행되면 oauth_external_authorization_status 변수를 읽습니다. 변수가 설정되어 있고 값이 true이면 Apigee는 클라이언트 사용자 인증 정보의 유효성 검사를 시도하지 않습니다. 변수가 설정되지 않거나 값이 true가 아니면 Apigee는 클라이언트 사용자 인증 정보의 유효성 검사를 시도합니다.

  • 가져올 외부 데이터를 지정할 수 있는 OAuthV2 정책에는 <ExternalAccessToken>, <ExternalRefreshToken>, <ExternalAuthorizationCode>의 세 가지 요소가 있습니다. 이러한 각 요소는 흐름 변수를 허용합니다. Apigee 정책은 해당 변수를 읽어 외부에서 생성된 액세스 토큰, 갱신 토큰 또는 승인 코드를 찾습니다. 정책과 로직을 구현하여 외부 토큰 또는 코드를 적절한 변수에 배치하는 것은 개발자의 몫입니다.

    예를 들어 OAuthV2 정책의 다음 구성은 Apigee에게 external_token이라는 컨텍스트 변수에서 토큰을 찾도록 지시합니다.

    <ExternalAccessToken>external_token</ExternalAccessToken>

    해당 변수를 설정하는 이전 단계도 필요합니다.

  • oauth_external_authorization_status 변수 설정과 관련하여 이 변수를 설정하는 일반적인 기법은 다음과 같이 AssignMessage 정책을 AssignVariable 요소와 함께 사용하는 것입니다.

    <AssignMessage name="AssignMessage-SetVariable">
        <DisplayName>Assign Message - Set Variable</DisplayName>
        <AssignVariable>
            <Name>oauth_external_authorization_status</Name>
            <Value>true</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    </AssignMessage>

    이 정책은 Operation = GenerateAccessToken인 OAuthV2 정책 이전이어야 합니다.

OAuthV2 정책 예시

다음 OAuthV2 정책은 Apigee가 흐름 변수 external_access_token에서 토큰 값을 찾은 경우 액세스 토큰을 생성합니다.

<OAuthV2 name="OAuth-v20-Store-External-Token">
    <DisplayName>OAuth v2.0 1</DisplayName>
    <Attributes/>
    <ExternalAccessToken>external_access_token</ExternalAccessToken>
    <ExternalAuthorization>true</ExternalAuthorization>
    <Operation>GenerateAccessToken</Operation>
    <GenerateResponse enabled="true">
        <Format>FORM_PARAM</Format>
    </GenerateResponse>
    <ReuseRefreshToken>false</ReuseRefreshToken>
    <StoreToken>true</StoreToken>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <ExpiresIn ref='flow.variable'>2400000</ExpiresIn>
</OAuthV2>

이론적으로는 이 패턴을 모든 타사 OAuth2 승인 서비스에 적용할 수 있습니다.