Skip to content

Incomplete and/or missing API Gateway Lambda Authorizer events #407

Open

Description

@marcogrcr

It seems there's a mismatch between the API Gateway Lambda authorizer event defintions and the Java classes available in this library.

Activity

  1. marcogrcr commented on Mar 2, 2023

    @marcogrcr
    Author

    API Gateway REST API (TOKEN)

    // https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html
    interface ApiGatewayRestTokenCustomAuthorizerEvent {
      type: "TOKEN";
      authorizationToken: string;
      methodArn: string;
    }

    The equivalent class is:

    Even though, this event is for API Gateway HTTP API (1.0), it contains a superset of the fields, so this class can be used here.

  2. marcogrcr commented on Mar 2, 2023

    @marcogrcr
    Author

    API Gateway REST API (REQUEST)

    // https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html
    interface ApiGatewayRestRequestCustomAuthorizerEvent {
      type: "REQUEST";
      methodArn: string;
      resource: string;
      path: string;
      httpMethod: string;
      headers: Record<string, string>;
      queryStringParameters: Record<string, string>;
      pathParameters: Record<string, string>;
      stageVariables: Record<string, string>;
      requestContext: {
        path: string;
        accountId: string;
        resourceId: string;
        stage: string;
        requestId: string;
        identity: {
          apiKey: string;
          sourceIp: string;
          clientCert: {
            clientCertPem: string;
            subjectDN: string;
            issuerDN: string;
            serialNumber: string;
            validity: {
              notBefore: string; // e.g. "May 28 12:30:02 2019 GMT"
              notAfter: string; // e.g. "Aug  5 09:36:04 2021 GMT"
            };
          };
        };
        resourcePath: string;
        httpMethod: string;
        apiId: string;
      };
    }

    The equivalent class is:

    Even though, this event is for API Gateway HTTP API (1.0), which contains a superset of the fields, it's missing the following:

    -       clientCert: {
    -         clientCertPem: string;
    -         subjectDN: string;
    -         issuerDN: string;
    -         serialNumber: string;
    -         validity: {
    -           notBefore: string; // e.g. "May 28 12:30:02 2019 GMT"
    -           notAfter: string; // e.g. "Aug  5 09:36:04 2021 GMT"
    -         };
    -       };

    Also, upon testing this manually, I see the following is also sent by API Gateway though not documented:

    interface Undocumented {
      multiValueHeaders: Record<string, string[]>;
      multiValueQueryStringParameters: Record<string, string[]>;
      requestContext: {
        extendedRequestId: string;
        requestTime: string; // e.g. "19/Jan/2023:21:13:26 +0000"
        protocol: string; // e.g. "HTTP/1.1"
        domainPrefix: string;
        requestTimeEpoch: number; // e.g. 1674162806345
        identity: {
          // in my testing API Gateway sent `null` to the fields with `unknown` type. So I don't know for sure
          cognitoIdentityPoolId: unknown; // likely `string`
          accountId: unknown; // likely `string`
          cognitoIdentityId: unknown; // likely `string`
          caller: unknown; // likely `string`
          principalOrgId: unknown; // likely `string`
          accessKey: unknown; // likely `string`
          cognitoAuthenticationType: unknown; // likely `string`
          cognitoAuthenticationProvider: unknown; // likely `string`
          userArn: unknown; // likely `string`
          userAgent: string;
          user: string;
        }
      }
    }

    In my opinion, the undocumented fields should be added too, so developers can take advantage of them. In particular $.requestContext.extendedRequestId is critical since it's the only field that provides end-to-end request tracing as clients can override the $.requestContext.requestId value by specifying the x-amzn-requestid header on their HTTP requests.

  3. marcogrcr commented on Mar 2, 2023

    @marcogrcr
    Author

    API Gateway HTTP API (1.0)

    // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html
    interface ApiGatewayHttp10CustomAuthorizerEvent {
      version: "1.0";
      type: "REQUEST";
      methodArn: string;
      identitySource: string;
      authorizationToken: string;
      resource: string;
      path: string;
      httpMethod: string;
      headers: Record<string, string>;
      queryStringParameters: Record<string, string>;
      pathParameters: Record<string, string>;
      stageVariables: Record<string, string>;
      requestContext: {
        path: string;
        accountId: string;
        resourceId: string;
        stage: string;
        requestId: string;
        identity: {
          apiKey: string;
          sourceIp: string;
          clientCert: {
            clientCertPem: string;
            subjectDN: string;
            issuerDN: string;
            serialNumber: string;
            validity: {
              notBefore: string; // e.g. "May 28 12:30:02 2019 GMT"
              notAfter: string; // e.g. "Aug  5 09:36:04 2021 GMT"
            };
          };
        };
        resourcePath: string;
        httpMethod: string;
        apiId: string;
      };
    }

    The equivalent class is:

    Which is missing the following:

    -       clientCert: {
    -         clientCertPem: string;
    -         subjectDN: string;
    -         issuerDN: string;
    -         serialNumber: string;
    -         validity: {
    -           notBefore: string; // e.g. "May 28 12:30:02 2019 GMT"
    -           notAfter: string; // e.g. "Aug  5 09:36:04 2021 GMT"
    -         };
    -       };
  4. marcogrcr commented on Mar 2, 2023

    @marcogrcr
    Author

    API Gateway HTTP API (2.0)

    // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html
    interface ApiGatewayHttp20CustomAuthorizerEvent {
      version: "2.0";
      type: "REQUEST";
      routeArn: string;
      identitySource: string[];
      routeKey: string;
      rawPath: string;
      rawQueryString: string;
      cookies: string[];
      headers: Record<string, string>;
      queryStringParameters: Record<string, string>;
      requestContext: {
        accountId: string;
        apiId: string;
        authentication: {
          clientCert: {
            clientCertPem: string;
            subjectDN: string;
            issuerDN: string;
            serialNumber: string;
            validity: {
              notBefore: string; // e.g. "May 28 12:30:02 2019 GMT"
              notAfter: string; // e.g. "Aug  5 09:36:04 2021 GMT"
            };
          };
        };
        domainName: string;
        domainPrefix: string;
        http: {
          method: string;
          path: string;
          protocol: string;
          sourceIp: string;
          userAgent: string;
        };
        requestId: string;
        routeKey: string;
        stage: string;
        time: string; // e.g. "12/Mar/2020:19:03:58 +0000";
        timeEpoch: number; // e.g. 1583348638390
      };
      pathParameters: Record<string, string>;
      stageVariables: Record<string, string>;
    }

    The equivalent class is:

    Which is missing the following:

    -     authentication: {
    -       clientCert: {
    -         clientCertPem: string;
    -         subjectDN: string;
    -         issuerDN: string;
    -         serialNumber: string;
    -         validity: {
    -           notBefore: string; // e.g. "May 28 12:30:02 2019 GMT"
    -           notAfter: string; // e.g. "Aug  5 09:36:04 2021 GMT"
    -         };
    -       };
    -     };
  5. marcogrcr commented on Mar 2, 2023

    @marcogrcr
    Author

    API Gateway WebSocket API

    // https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-lambda-auth.html
    interface ApiGatewayWebSocketCustomAuthorizerEvent {
      type: "REQUEST";
      methodArn: string;
      headers: Record<string, string>;
      multiValueHeaders: Record<string, string[]>;
      queryStringParameters: Record<string, string>;
      multiValueQueryStringParameters: Record<string, string[]>;
      stageVariables: Record<string, string>;
      requestContext: {
        routeKey: "$connect";
        eventType: "CONNECT";
        extendedRequestId: string;
        requestTime: string; // e.g. "19/Jan/2023:21:13:26 +0000"
        messageDirection: "IN";
        stage: string;
        connectedAt: number; // e.g. 1674162806344
        requestTimeEpoch: number; // e.g. 1674162806345
        identity: {
          userAgent: string; // missing from docs but present in a proof-of-concept
          sourceIp: string;
        };
        requestId: string;
        domainName: string;
        connectionId: string;
        apiId: string;
      };
    }

    There is no equivalent class for this event type. The closest one is:

    But it's missing the following:

    -   multiValueHeaders: Record<string, string[]>;
    -   multiValueQueryStringParameters: Record<string, string[]>;
        requestContext: {
    -     routeKey: "$connect";
    -     eventType: "CONNECT";
    -     extendedRequestId: string;
    -     requestTime: string; // e.g. "19/Jan/2023:21:13:26 +0000"
    -     messageDirection: "IN";
          stage: string;
    -     connectedAt: number; // e.g. 1674162806344
    -     requestTimeEpoch: number; // e.g. 1674162806345
          identity: {
    -       userAgent: string; // missing from docs but present in a proof-of-concept
            sourceIp: string;
          };
          requestId: string;
    -     domainName: string;
    -     connectionId: string;
          apiId: string;
        };

    After performing a manual test, I believe the following class should be created to address this gap:

    package com.amazonaws.services.lambda.runtime.events;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.List;
    import java.util.Map;
    
    
    @Data
    @Builder(setterPrefix = "with")
    @NoArgsConstructor
    @AllArgsConstructor
    public class APIGatewayV2WebSocketCustomAuthorizerEvent {
        private String type;
        private String methodArn;
        private Map<String, String> headers;
        private Map<String, List<String>> multiValueHeaders;
        private Map<String, String> queryStringParameters;
        private Map<String, List<String>> multiValueQueryStringParameters;
        private Map<String, String> stageVariables;
        private RequestContext requestContext;
    
        @Data
        @Builder(setterPrefix = "with")
        @NoArgsConstructor
        @AllArgsConstructor
        public static class RequestContext {
            private String routeKey;
            private String eventType;
            private String extendedRequestId;
            private String requestTime;
            private String messageDirection;
            private String stage;
            private long connectedAt;
            private long requestTimeEpoch;
            private Identity identity;
            private String requestId;
            private String domainName;
            private String connectionId;
            private String apiId;
        }
    
        @Data
        @Builder(setterPrefix = "with")
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Identity {
            private String userAgent;
            private String sourceIp;
        }
    }
  6. changed the title [-]Incomplete and missing API Gateway Lambda Authorizer events[/-] [+]Incomplete and/or missing API Gateway Lambda Authorizer events[/+] on Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions