

# Controlar o acesso a APIs HTTP com autorizadores JWT no API Gateway
<a name="http-api-jwt-authorizer"></a>

O JSON Web Tokens (JWTs) pode ser usado como parte das estruturas [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) e [OAuth 2.0](https://oauth.net/2/) para que você possa restringir o acesso do cliente às suas APIs.

Se você configurar um autorizador JWT para uma rota da sua API, o API Gateway valida os JWTs enviados pelos clientes com solicitações de API. O API Gateway aceita ou rejeita solicitações com base na validação de tokens e, opcionalmente, escopos no token. Se você configurar escopos para uma rota, o token deverá incluir pelo menos um dos escopos da rota.

Você pode configurar autorizadores distintos para cada rota de uma API ou usar o mesmo autorizador para várias rotas.

**nota**  
Não existe nenhum mecanismo padrão para diferenciar tokens de acesso JWT de outros tipos de JWTs, como os tokens OpenID e Connect ID. Exceto se precisar de tokens de ID para autorização de API, recomendamos que você configure suas rotas para exigir escopos de autorização. Você também pode configurar seus autorizadores do JWT para exigir emissores ou públicos que seu provedor de identidade usa somente ao emitir tokens de acesso do JWT.

## Autorização de solicitações de API com um autorizador JWT
<a name="http-api-jwt-authorizer.evaluation"></a>

O API Gateway usa o fluxo de trabalho geral a seguir para autorizar solicitações para rotas configuradas para usar um autorizador JWT. 

1. Verifique se há um token em [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-prop-authorizer-identitysource](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-prop-authorizer-identitysource). O `identitySource` pode incluir apenas o token ou o token com o prefixo `Bearer`.

1. Decodifique o token.

1. Verifique o algoritmo e a assinatura do token usando a chave pública obtida do do emisso `jwks_uri`. No momento, somente algoritmos baseados em RSA são compatíveis. O API Gateway pode armazenar a chave pública em cache por duas horas. Como prática recomendada, ao alternar as chaves, aguarde um período de carência durante o qual as chaves antigas e novas sejam válidas. 

1. Valide reivindicações. O API Gateway avalia as seguintes reivindicações de token:
   +  [https://datatracker.ietf.org/doc/html/rfc7517#section-4.5](https://datatracker.ietf.org/doc/html/rfc7517#section-4.5): o token deve ter uma reivindicação de cabeçalho que corresponda à chave no `jwks_uri` que assinou o token.
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1): deve corresponder ao [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration) configurado para o autorizador.
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) ou `client_id`: deve corresponder a uma das entradas [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration) configuradas para o autorizador. O API Gateway valida `client_id` somente se `aud` não estiver presente. Quando `aud` e `client_id` estão presentes, o API Gateway avalia `aud`.
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) – deve ser após a hora atual em UTC. 
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) – deve ser antes da hora atual em UTC. 
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6) – deve ser antes da hora atual em UTC. 
   + [https://datatracker.ietf.org/doc/html/rfc6749#section-3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3) ou `scp`: o token deve incluir pelo menos um dos escopos em [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid.html#apis-apiid-routes-routeid-prop-updaterouteinput-authorizationscopes](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid.html#apis-apiid-routes-routeid-prop-updaterouteinput-authorizationscopes) da rota.

Se qualquer uma dessas etapas falhar, o API Gateway negará a solicitação de API.

Depois de validar o JWT, o API Gateway passa as alegações no token para a integração da rota da API. Recursos de backend, como as funções do Lambda, podem acessar as alegações de JWT. Por exemplo, se o JWT incluiu um `emailID` de alegação de identidade, ele estará disponível para uma integração do Lambda em `$event.requestContext.authorizer.jwt.claims.emailID`. Para obter mais informações sobre a carga útil que o API Gateway envia para integrações do Lambda, consulte [Criar integrações de proxy AWS Lambda para APIs HTTP no API Gateway](http-api-develop-integrations-lambda.md).

## Criar um autorizador de JWT
<a name="http-api-jwt-authorizer.create"></a>

Antes de criar um autorizador de JWT, você deve registrar um aplicativo cliente com um provedor de identidade. Também deve ter criado uma API HTTP. Para obter exemplos de criação de uma API HTTP, consulte [Criar uma API HTTP](http-api-develop.md#http-api-examples).

### Criar um autorizador JWT usando o console
<a name="http-api-jwt-authorizer.create.console"></a>

As etapas a seguir mostram como criar o autorizador JWT usando o console.

**Criar um autorizador JWT usando o console**

1. Faça login no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Selecione uma API HTTP.

1. No painel de navegação principal, selecione **Autorização**.

1. Escolha a guia **Gerenciar autorizadores**.

1. Escolha **Criar**.

1. Em **Tipo de autorizador**, escolha **JWT**.

1. Configure o autorizador JWT e especifique uma **Origem da identidade** que defina a origem do token.

1. Escolha **Criar**.

#### Criar um autorizador JWT usando a AWS CLI
<a name="http-api-jwt-authorizer.create.cli"></a>

O comando [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-authorizer.html) a seguir cria um autorizador de JWT. Para `jwt-configuration`, especifique o `Audience` e o `Issuer` para seu provedor de identidades. Se você usa o Amazon Cognito como provedor de identidade, o `IssuerUrl` é `https://cognito-idp.us-east-2.amazonaws.com/userPoolID`.

```
aws apigatewayv2 create-authorizer \
    --name authorizer-name \
    --api-id api-id \
    --authorizer-type JWT \
    --identity-source '$request.header.Authorization' \
    --jwt-configuration Audience=audience,Issuer=IssuerUrl
```

##### Criar um autorizador de AWS CloudFormation
<a name="http-api-jwt-cfn.create"></a>

O modelo CloudFormation a seguir cria uma API HTTP com um autorizador JWT usando o Amazon Cognito como provedor de identidade.

A saída do modelo CloudFormation é um URL para uma interface de usuário hospedada no Amazon Cognito, na qual os clientes podem se inscrever e fazer login para receber um JWT. Depois que o cliente faz login, é redirecionado para sua API HTTP com um token de acesso no URL. Para invocar a API com o token de acesso, altere o `#` no URL para um `?` para usar o token como um parâmetro de string de consulta.

##### Exemplo de modelo CloudFormation
<a name="http-api-jwt-cfn-example"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: |
  Example HTTP API with a JWT authorizer. This template includes an Amazon Cognito user pool as the issuer for the JWT authorizer 
  and an Amazon Cognito app client as the audience for the authorizer. The outputs include a URL for an Amazon Cognito hosted UI where clients can 
  sign up and sign in to receive a JWT. After a client signs in, the client is redirected to your HTTP API with an access token 
  in the URL. To invoke the API with the access token, change the '#' in the URL to a '?' to use the token as a query string parameter.

Resources:
  MyAPI:
    Type: AWS::ApiGatewayV2::Api
    Properties: 
      Description: Example HTTP API
      Name: api-with-auth
      ProtocolType: HTTP
      Target: !GetAtt MyLambdaFunction.Arn
  DefaultRouteOverrides:
    Type: AWS::ApiGatewayV2::ApiGatewayManagedOverrides
    Properties: 
      ApiId: !Ref MyAPI
      Route: 
        AuthorizationType: JWT
        AuthorizerId: !Ref JWTAuthorizer
  JWTAuthorizer:
    Type: AWS::ApiGatewayV2::Authorizer
    Properties: 
      ApiId: !Ref MyAPI
      AuthorizerType: JWT
      IdentitySource: 
        - '$request.querystring.access_token'
      JwtConfiguration: 
        Audience: 
        - !Ref AppClient
        Issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${UserPool}
      Name: test-jwt-authorizer
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs18.x
      Role: !GetAtt FunctionExecutionRole.Arn
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async (event) => {
              const response = {
                  statusCode: 200,
                  body: JSON.stringify('Hello from the ' + event.routeKey + ' route!'),
              };
              return response;
          };
  APIInvokeLambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref MyLambdaFunction
      Action: lambda:InvokeFunction
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${MyAPI}/$default/$default
  FunctionExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17		 	 	 '
        Statement:
          - Effect: Allow
            Principal:
              Service:
              - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: http-api-user-pool
      AutoVerifiedAttributes:
        - email
      Schema:
        - Name: name
          AttributeDataType: String
          Mutable: true
          Required: true
        - Name: email
          AttributeDataType: String
          Mutable: false
          Required: true
  AppClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      AllowedOAuthFlows: 
        - implicit
      AllowedOAuthScopes: 
        - aws.cognito.signin.user.admin
        - email
        - openid
        - profile
      AllowedOAuthFlowsUserPoolClient: true
      ClientName: api-app-client
      CallbackURLs:
        - !Sub https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com
      ExplicitAuthFlows:
        - ALLOW_USER_PASSWORD_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      UserPoolId: !Ref UserPool
      SupportedIdentityProviders:
        - COGNITO 
  HostedUI:
    Type: AWS::Cognito::UserPoolDomain
    Properties: 
      Domain: !Join
        - '-'
        - - !Ref MyAPI
          - !Ref AppClient
      UserPoolId: !Ref UserPool
Outputs:
  SignupURL:
    Value: !Sub https://${HostedUI}.auth.${AWS::Region}.amazoncognito.com/login?client_id=${AppClient}&response_type=token&scope=email+profile&redirect_uri=https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com
```

## Atualizar uma rota para usar um autorizador JWT
<a name="http-api-jwt-authorizer.create.route"></a>

Você pode usar o console, a AWS CLI ou um AWS SDK para atualizar uma rota para usar um autorizador JWT.

### Atualizar uma rota para usar um autorizador JWT com o console
<a name="http-api-jwt-authorizer.create.route"></a>

As etapas a seguir mostram como atualizar uma rota para usar o autorizador JWT com o console.

**Para criar um autorizador JWT usando o console**

1. Faça login no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Selecione uma API HTTP.

1. No painel de navegação principal, selecione **Autorização**.

1. Escolha um método, selecione o autorizador no menu suspenso e escolha **Anexar autorizador**.

#### Atualizar uma rota para usar um autorizador JWT com a AWS CLI
<a name="http-api-jwt-authorizer.create.route"></a>

O comando [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) indicado abaixo atualiza uma rota para usar um autorizador de JWT:

```
aws apigatewayv2 update-route \
   --api-id api-id  \
   --route-id route-id  \
   --authorization-type JWT \
   --authorizer-id authorizer-id \
   --authorization-scopes user.email
```