Como usar tokens do OAuth de terceiros

Esta página se aplica à Apigee e à Apigee híbrida.

Confira a documentação da Apigee Edge.

Neste tópico, discutiremos como importar tokens de acesso gerados externamente, tokens de atualização ou códigos de autenticação no armazenamento de tokens da Apigee. Use essa técnica se quiser configurar a Apigee para validar tokens gerados fora da Apigee.

Normalmente, a Apigee vai gerar e armazenar um token OAuth e retorná-lo ao aplicativo que fez a chamada. Em seguida, o aplicativo de chamada apresenta o token de volta à Apigee ao solicitar serviço. Por meio da política OAuthV2 com operação = VerifyAccessToken, a Apigee irá verificar se o token é válido. Este tópico descreve como configurar a Apigee para armazenar um token OAuth gerado em outro lugar, mantendo a verificação de token igual, como se ele fosse gerado pela Apigee.

Exemplo

Se você quiser ver um exemplo funcional que ilustra a técnica descrita neste tópico, consulte o exemplo de gerenciamento de token delegado da Apigee.

O que é isso?

Suponha que você tem um sistema existente de autorização e quer usar os valores de token ou de código gerados por esse sistema nem vez do valor do token OAuth2 ou dos valores de código gerados pela Apigee. É possível fazer solicitações seguras de proxy de API com o token ou o código substituído, e a Apigee as validará como se fossem geradas por ela.

Algum plano de fundo

Normalmente, a Apigee gera um token produzindo uma string aleatória de letras e números. A Apigee associa outros dados a esse token, como a hora em que ele foi emitido, a expiração, a lista de produtos da API para os quais o token é válido e o escopo. Todas essas informações podem ser retornadas em uma resposta gerada automaticamente pela política OAuthV2 configurada com Operation = GenerateAccessToken. A resposta será assim:

{
  "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 pela Apigee para recuperar os metadados do token. Por exemplo, suponha que uma solicitação de proxy de API inclua o token do portador zBC90HhCGmGlaMBWeZAai2s3za5j. Usando o valor do token, a Apigee recupera os metadados do token para determinar se ele é válido ou não.

Seguindo as etapas descritas aqui é possível configurar a Apigee para armazenar um token. Assim, o valor de access_token será algo gerado por um serviço externo. Por exemplo, suponha que você tem um sistema externo à Apigee que gera tokens no formato "TOKEN-<16 números aleatórios>". Nesse caso, os metadados completos do token armazenados pela 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"
}

Nesse caso, um app pode fazer uma solicitação a um proxy de API, carregando o token do portador TOKEN-1092837373654221, e a Apigee poderá validá-lo. É possível aplicar um padrão de importação semelhante aos códigos de autorização e aos tokens de atualização.

Vamos falar sobre como validar credenciais de cliente

Um pré-requisito para gerar um token é validar o cliente solicitante. Por padrão, a política OAuthV2/GenerateAccessToken na Apigee verifica implicitamente as credenciais do cliente. Normalmente, em uma solicitação de um token OAuthV2, o client_id e a client_secret são transmitidos no cabeçalho de autorização e codificados por meio de autorização básica HTTP (com concatenação de dois pontos, depois codificada em base64). A política OAuthV2/GenerateAccessToken na Apigee decodifica o cabeçalho, pesquisa o client_id e verifica se o client_secret transmitido é válido para esse client_id. Isso funciona se as credenciais forem conhecidas pela Apigee: em outras palavras, há um aplicativo do desenvolvedor armazenado dentro da Apigee com uma credencial que contém os client_id e client_secret fornecidos.

Caso as credenciais do cliente não sejam validadas pela Apigee, é necessário projetar o proxy da API antes que ele gere um token para validar explicitamente o cliente por outros meios. Geralmente, isso é feito por meio de uma política ServiceCallout que se conecta a um endpoint remoto na sua rede.

De uma forma ou de outra, implícita ou explicitamente, você precisa garantir que o proxy da API que gera tokens valide primeiro as credenciais do cliente. A validação do cliente é independente de gerar o token de acesso. É possível configurar a Apigee para fazer as duas tarefas: ou uma ou nenhuma delas.

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

A Apigee pode não validar as credenciais do cliente, mas ainda é necessário que client_id seja conhecido e gerenciado pela Apigee. Todo acesso_token na Apigee, gerado por ela ou por um sistema externo e importado para ela precisa estar associado a um aplicativo cliente, indicado por client_id. Portanto, mesmo no caso em que a política OAuthV2/GenerateAccessToken na Apigee não valida a correspondência de client_id e client_secret, a política validará que client_id é válido, presente, e não revogado. Portanto, como uma etapa de configuração de pré-requisito, talvez seja necessário importar o client_id por meio da API administrativa da Apigee.

Fluxo de política para OAuth de terceiros na Apigee

Para usar tokens de sistemas OAuth de terceiros na Apigee, o fluxo para gerar tokens de acesso precisa seguir um dos seguintes padrões.

Validação externa de credenciais de cliente

  1. ServiceCallout para verificar as credenciais de entrada do cliente e adquirir um token externo.
  2. ExtractVariables ou uma etapa JavaScript para extrair o token gerado externamente da resposta.
  3. AssignMessage para definir a variável especial conhecida chamada oauth_external_authorization_status. O valor precisa ser true 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 de <ExternalAccessToken>, <ExternalRefreshToken> ou <ExternalAuthorizationCode>.

Validação interna de credenciais de cliente

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

Observações sobre a configuração de fluxo e política

  • Caso queira usar um sistema externo para validar as credenciais do cliente, cabe a você desenvolver um fluxo de política que faça o que é necessário. Normalmente, você usaria uma política ServiceCalling para enviar as credenciais reconhecidas externamente para o serviço de autenticação externo. O serviço de autenticação externo normalmente retorna uma resposta e, se as credenciais forem válidas, também será um token de acesso.

  • Após a ServiceCallout, o proxy da API precisa analisar a resposta para extrair o status 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 o elemento <ExternalAuthorization> como true ou false conforme apropriado.

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

  • Há três elementos para a política OAuthV2 que permite especificar os dados externos a serem importados: <ExternalAccessToken>, <ExternalRefreshToken> e <ExternalAuthorizationCode>. Cada um desses elementos aceita uma variável de fluxo. A política da Apigee lerá essa variável para encontrar o token de acesso gerado externamente, o token de atualização ou o código de autorização. Cabe a você implementar políticas e lógica para colocar os tokens ou códigos externos nas variáveis apropriadas.

    Por exemplo, a seguinte configuração na política do OAuthV2 instrui a Apigee a procurar o token em uma variável de contexto chamada external_token.

    <ExternalAccessToken>external_token</ExternalAccessToken>

    Você também precisa ter uma etapa anterior que defina essa variável.

  • Com relação à configuração da variável oauth_external_authorization_status, uma técnica comum para definir essa 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 essa política precisa estar antes da política OAuthV2 com Operation = GenerateAccessToken.

Exemplo de política do OAuthV2

A seguinte política do OAuthV2 gera um token de acesso porque a 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>

Teoricamente, você pode aplicar esse padrão com qualquer serviço de autorização OAuth2 de terceiros.