Usar tokens OAuth de terceiros

Esta página aplica-se ao Apigee e ao Apigee Hybrid.

Veja a documentação do Apigee Edge.

Neste tópico, vamos abordar como importar chaves de acesso, chaves de atualização ou códigos de autorização gerados externamente para o arquivo de tokens do Apigee. Pode usar esta técnica se quiser configurar o Apigee para validar tokens gerados fora do Apigee.

No caso habitual, o Apigee gera e armazena um token OAuth e devolve-o à aplicação de chamada. Em seguida, a app de chamada apresenta esse token novamente ao Apigee quando solicita o serviço, e o Apigee, através da política OAuthV2 com Operation = VerifyAccessToken, verifica se o token é válido. Este tópico descreve como pode configurar o Apigee para armazenar um token OAuth gerado noutro local, mantendo a parte de validação do token igual, tal como se o token tivesse sido gerado pelo Apigee.

Exemplo

Se quiser ver um exemplo funcional que ilustre a técnica descrita neste tópico, consulte o exemplo de gestão de tokens delegada do Apigee.

O que é isto?

Suponhamos que tem um sistema de autorização existente e quer usar os valores de token ou código gerados por esse sistema em vez dos valores de token ou código OAuth2 que o Apigee gera. Em seguida, pode fazer pedidos de proxy de API seguros com o código ou o token substituído, e o Apigee valida-os como se tivessem sido gerados pelo Apigee.

Alguns antecedentes

Normalmente, o Apigee gera um token produzindo uma string aleatória de letras e números. O Apigee associa a esse token outros dados, como a hora em que o token foi emitido, a data de validade, a lista de produtos de API para os quais o token é válido e o âmbito. Todas estas informações podem ser devolvidas numa resposta gerada automaticamente pela política OAuthV2 configurada com Operation = GenerateAccessToken. A resposta tem o seguinte aspeto:

{
  "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"
}

O valor access_token é usado pelo Apigee para obter os metadados do token. Por exemplo, suponha que um pedido de proxy da API inclui o token de autorização zBC90HhCGmGlaMBWeZAai2s3za5j. Usando o valor do token, o Apigee obtém os metadados do token para determinar se o token é válido ou não.

Seguindo os passos descritos aqui, pode configurar o Apigee para armazenar um token cujo valor access_token foi gerado por um serviço externo. Por exemplo, suponha que tem um sistema externo ao Apigee que gera tokens no formato "TOKEN-<16 números aleatórios>" . Nesse caso, os metadados do token completos armazenados pelo Apigee podem ser:

{
  "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"
}

Neste caso, uma app pode fazer um pedido a um proxy de API, com o token de portador TOKEN-1092837373654221, e o Apigee vai poder validá-lo. Pode aplicar um padrão de importação semelhante a códigos de autorização e tokens de atualização.

Vamos falar sobre a validação das credenciais do cliente

Um pré-requisito para gerar um token é validar o cliente que está a fazer o pedido. Por predefinição, a política OAuthV2/GenerateAccessToken no Apigee valida implicitamente as credenciais do cliente. Normalmente, num pedido de um token OAuthV2, o client_id e o client_secret são transmitidos no cabeçalho de autorização, codificados através da autorização básica HTTP (concatenados com dois pontos e, em seguida, codificados em base64). A política OAuthV2/GenerateAccessToken no Apigee descodifica esse cabeçalho e procura o client_id e verifica se o client_secret transmitido é válido para esse client_id. Isto funciona se o Apigee conhecer as credenciais, ou seja, se existir uma app de programador armazenada no Apigee que contenha uma credencial, que, por sua vez, contenha o client_id e o client_secret indicados.

Caso as credenciais do cliente não devam ser validadas pelo Apigee, tem de conceber o proxy de API, antes de gerar um token, para validar explicitamente o cliente através de outros meios. Muitas vezes, isto é feito através de uma política ServiceCallout que se liga a um ponto final remoto na sua rede.

De uma forma ou de outra, implícita ou explicitamente, tem de garantir que o proxy de API que gera tokens valida primeiro as credenciais do cliente. Tenha em atenção que a validação do cliente é independente da geração do token de acesso. Pode configurar o Apigee para fazer ambas as ações, ou para fazer uma ou outra, ou nenhuma.

Se quiser que a política OAuthV2/GenerateAccessToken no Apigee valide as credenciais do cliente em relação ao armazenamento do Apigee, defina o elemento <ExternalAuthorization> como false na configuração da política ou omita-o por completo. Se quiser usar um serviço de autorização externo para validar explicitamente as credenciais do cliente, defina <ExternalAuthorization> como true.

Embora o Apigee possa não validar as credenciais do cliente, continua a ser necessário que o client_id seja conhecido e gerido pelo Apigee. Todos os access_token no Apigee, quer sejam gerados pelo Apigee ou por um sistema externo e, em seguida, importados para o Apigee, têm de estar associados a uma aplicação cliente, indicada pelo client_id. Assim, mesmo no caso em que a política OAuthV2/GenerateAccessToken no Apigee não valida se o client_id e o client_secret correspondem, a política valida se o client_id é válido, está presente e não foi revogado. Como passo de configuração pré-requisito, pode ter de importar client_id através da API administrativa do Apigee.

Fluxo de políticas para OAuth de terceiros no Apigee

Para usar tokens de sistemas OAuth de terceiros no Apigee, o fluxo de geração de tokens de acesso deve seguir um dos seguintes padrões.

Validação externa das credenciais do cliente

  1. ServiceCallout para validar as credenciais do cliente de entrada e adquirir um token externo.
  2. ExtractVariables ou um passo JavaScript para extrair o token gerado externamente da resposta.
  3. AssignMessage para definir a variável conhecida especial denominada oauth_external_authorization_status. O valor tem de ser verdadeiro para indicar que as credenciais do cliente são válidas.
  4. OAuthV2/GenerateAccessToken com o elemento <ExternalAuthorization> definido como true e, pelo menos, um dos seguintes elementos: <ExternalAccessToken>, <ExternalRefreshToken> ou <ExternalAuthorizationCode>.

Validação interna das credenciais do cliente

  • ServiceCallout para adquirir um token externo.
  • ExtractVariables ou um passo JavaScript para extrair o token gerado externamente da resposta.
  • OAuthV2/GenerateAccessToken com o elemento <ExternalAuthorization> definido como false e, pelo menos, um dos seguintes elementos: <ExternalAccessToken>, <ExternalRefreshToken> ou <ExternalAuthorizationCode>.

Notas sobre o fluxo e a configuração de políticas

  • Caso queira usar um sistema externo para validar as credenciais do cliente, é da sua responsabilidade desenvolver um fluxo de políticas que faça o que for necessário. Normalmente, usaria uma política ServiceCallout para enviar as credenciais reconhecidas externamente para o serviço de autenticação externo. Normalmente, o serviço de autenticação externo devolve uma resposta e, se as credenciais forem válidas, também um token de acesso.

  • Após o ServiceCallout, o proxy de API tem de analisar a resposta para extrair o estado de validade, bem como o access_token gerado externamente e, possivelmente, o refresh_token.

  • Na política OAuthV2/GenerateAccessToken, defina o elemento <StoreToken> como true e defina o elemento <ExternalAuthorization> como true ou false, conforme adequado.

    Quando a política OAuthV2/GenerateAccessToken é executada, lê a variável oauth_external_authorization_status. Se a variável estiver definida e o valor for verdadeiro, o Apigee não tenta validar as credenciais do cliente. Se a variável não estiver definida ou o valor não for verdadeiro, o Apigee tenta validar as credenciais do cliente.

  • Existem três elementos para a política OAuthV2 que lhe permitem especificar os dados externos a importar: <ExternalAccessToken>, <ExternalRefreshToken> e <ExternalAuthorizationCode>. Cada um destes elementos aceita uma variável de fluxo. A política do Apigee lê essa variável para encontrar o token de acesso, o token de atualização ou o código de autorização gerado externamente. É da sua responsabilidade implementar políticas e lógica para colocar os tokens ou os códigos externos nas variáveis adequadas.

    Por exemplo, a seguinte configuração na política OAuthV2 indica ao Apigee que procure o token numa variável de contexto denominada external_token.

    <ExternalAccessToken>external_token</ExternalAccessToken>

    Também precisa de ter um passo anterior que defina essa variável.

  • Relativamente à definição da variável oauth_external_authorization_status, uma técnica comum para definir esta variável é usar uma política AssignMessage com o elemento AssignVariable, da seguinte forma:

    <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>

    Lembre-se de que esta política tem de ser aplicada antes da política OAuthV2 com Operation = GenerateAccessToken.

Exemplo de política de OAuthV2

A seguinte política OAuthV2 gera um token de acesso, dado que o Apigee encontra um valor de token na variável de fluxo 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>

Em teoria, pode aplicar este padrão com qualquer serviço de autorização OAuth2 de terceiros.