

# Control del acceso a API HTTP con autorizadores de JWT en API Gateway
<a name="http-api-jwt-authorizer"></a>

Puede utilizar tokens web JSON (JWT) como parte de los marcos [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) y [OAuth 2.0](https://oauth.net/2/) para restringir el acceso de clientes a las API.

Si configura un autorizador de JWT para una ruta de la API, API Gateway valida los JWT que los clientes envían con solicitudes de la API. API Gateway permite o deniega las solicitudes en función de la validación del token y, opcionalmente, de los ámbitos del token. Si configura ámbitos para una ruta, el token debe incluir al menos uno de los ámbitos de la ruta.

Puede configurar distintos autorizadores para cada ruta de una API o utilizar el mismo autorizador para varias rutas.

**nota**  
No existe ningún mecanismo estándar para diferenciar los tokens de acceso de JWT de otros tipos de JWT, como los tokens de ID de OpenID Connect. A menos que necesite tokens de ID para la autorización de la API, le recomendamos que configure las rutas para que soliciten los ámbitos de la autorización. También puede configurar los autorizadores de JWT para que soliciten los emisores o los destinatarios que utiliza el proveedor de identidades solo al emitir tokens de acceso de JWT.

## Autorización de solicitudes de API con un autorizador de JWT
<a name="http-api-jwt-authorizer.evaluation"></a>

API Gateway utiliza el siguiente flujo de trabajo general para autorizar solicitudes a rutas configuradas para utilizar un autorizador de JWT. 

1. Comprueba si [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) contiene un token. `identitySource` puede incluir solo el token o el token con el prefijo `Bearer`.

1. Descodifique el token.

1. Compruebe el algoritmo y la firma del token tilizando la clave pública obtenida del del emiso `jwks_uri`. Actualmente solo se admiten algoritmos basados en RSA. API Gateway puede almacenar en caché la clave pública durante dos horas. Al rotar las claves, se recomienda dejar un período de gracia durante el cual tanto la clave antigua como la nueva sean válidas. 

1. Valide las reclamaciones. API Gateway evalúa las siguientes reclamaciones de token:
   +  [https://datatracker.ietf.org/doc/html/rfc7517#section-4.5](https://datatracker.ietf.org/doc/html/rfc7517#section-4.5): el token debe tener una reclamación de encabezado que coincida con la clave de `jwks_uri` que firmó el token.
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1): debe coincidir con el [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 el autorizador.
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) o `client_id`: deben coincidir con una de las entradas de [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 el autorizador. API Gateway valida `client_id` solo si `aud` no está presente. Cuando `aud` y `client_id` están presentes, API Gateway evalúa `aud`.
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4): debe ser posterior a la hora actual en UTC. 
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5): debe ser anterior a la hora actual en UTC. 
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6): debe ser anterior a la hora actual en UTC. 
   + [https://datatracker.ietf.org/doc/html/rfc6749#section-3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3) o `scp`: el token debe incluir al menos uno de los ámbitos de los [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) de la ruta.

Si falla alguno de estos pasos, API Gateway deniega la solicitud de la API.

Después de validar el JWT, API Gateway transfiere las reclamaciones del token a la integración de la ruta de la API. Los recursos de backend, como las funciones de Lambda, pueden acceder a las reclamaciones de JWT. Por ejemplo, si el JWT incluye una reclamación de identidad `emailID`, esta estará disponible para una integración de Lambda en `$event.requestContext.authorizer.jwt.claims.emailID`. Para obtener más información acerca de la carga que API Gateway envía a las integraciones de Lambda, consulte [Creación de integraciones de proxy de AWS Lambda para las API de HTTP en API Gateway](http-api-develop-integrations-lambda.md).

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

Antes de crear un autorizador de JWT, debe registrar una aplicación cliente con un proveedor de identidad. También debe haber creado una API HTTP. Para obtener ejemplos de creación de una API HTTP, consulte [Creación de una API de HTTP](http-api-develop.md#http-api-examples).

### Creación de un autorizador de JWT a través de la consola
<a name="http-api-jwt-authorizer.create.console"></a>

Los siguientes pasos muestran cómo crear un autorizador de JWT mediante la consola.

**Creación de un autorizador de JWT a través de la consola**

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Elija una API HTTP.

1. En el panel de navegación principal, elija **Autorización**.

1. Elija la pestaña **Administrar autorizadores**.

1. Seleccione **Crear**.

1. Para **Tipo de autorizador**, elija **JWT**.

1. Configure el autorizador de JWT y especifique un **Origen de identidad** que defina el origen del token.

1. Seleccione **Crear**.

#### Creación de un autorizador de JWT con la AWS CLI
<a name="http-api-jwt-authorizer.create.cli"></a>

El siguiente comando [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-authorizer.html) crea un autorizador de JWT. Para `jwt-configuration`, especifique la `Audience` y el `Issuer` del proveedor de identidades. Si utiliza Amazon Cognito como proveedor de identidades, `IssuerUrl` es `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
```

##### Creación de un autorizador de JWT a través de AWS CloudFormation
<a name="http-api-jwt-cfn.create"></a>

La siguiente plantilla de CloudFormation crea una API HTTP con un autorizador de JWT que usa Amazon Cognito como proveedor de identidades.

El resultado de la plantilla de CloudFormation es una URL de una interfaz de usuario alojada de Amazon Cognito en la que los clientes pueden registrarse e iniciar sesión para recibir un JWT. Cuando un cliente inicia sesión, se le redirige a la API HTTP con un token de acceso en la URL. Para invocar la API con el token de acceso, cambie `#` en la URL por `?` para usar el token como un parámetro de cadena de consulta.

##### Plantilla de CloudFormation de ejemplo
<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
```

## Actualización de una ruta para utilizar un autorizador de JWT
<a name="http-api-jwt-authorizer.create.route"></a>

Puede usar la consola, la AWS CLI, o un AWS SDK para actualizar una ruta y usar un autorizador de JWT.

### Actualización de una ruta para utilizar un autorizador de JWT a través de la consola
<a name="http-api-jwt-authorizer.create.route"></a>

Los siguientes pasos muestran cómo actualizar una ruta para usar un autorizador de JWT mediante la consola.

**Creación de un autorizador de JWT a través de la consola**

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Elija una API HTTP.

1. En el panel de navegación principal, elija **Autorización**.

1. Elija un método y, a continuación, seleccione el autorizador del menú desplegable y elija **Asociar autorizador**.

#### Actualización de una ruta para utilizar un autorizador de JWT a través de la AWS CLI
<a name="http-api-jwt-authorizer.create.route"></a>

El siguiente comando [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) actualiza una ruta para que utilice un 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
```