Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
marcogrcr opened this issue Mar 2, 2023 · 5 comments
Open

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

marcogrcr opened this issue Mar 2, 2023 · 5 comments

Comments

@marcogrcr
Copy link

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

@marcogrcr
Copy link
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.

@marcogrcr
Copy link
Author

marcogrcr commented Mar 2, 2023

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.

@marcogrcr
Copy link
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"
-         };
-       };

@marcogrcr
Copy link
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"
-         };
-       };
-     };

@marcogrcr
Copy link
Author

marcogrcr commented Mar 2, 2023

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

@marcogrcr marcogrcr changed the title Incomplete and missing API Gateway Lambda Authorizer events Incomplete and/or missing API Gateway Lambda Authorizer events Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant