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

Add support for IAM Authorizers in combination with 2.0 payload #815

Merged
merged 1 commit into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,21 @@
public class HttpApiV2AuthorizerMap extends HashMap<String, Object> {
private static final String JWT_KEY = "jwt";
private static final String LAMBDA_KEY = "lambda";
private static final String IAM_KEY = "iam";
private static final long serialVersionUID = 42L;

public HttpApiV2JwtAuthorizer getJwtAuthorizer() {
return (HttpApiV2JwtAuthorizer)get(JWT_KEY);
return (HttpApiV2JwtAuthorizer) get(JWT_KEY);
}

public Map<String, Object> getLambdaAuthorizerContext() {
return (Map<String, Object>) get(LAMBDA_KEY);
}

public HttpApiV2IamAuthorizer getIamAuthorizer() {
return (HttpApiV2IamAuthorizer) get(IAM_KEY);
}

public boolean isJwt() {
return containsKey(JWT_KEY);
}
Expand All @@ -52,10 +57,18 @@ public boolean isLambda() {
return containsKey(LAMBDA_KEY);
}

public boolean isIam() {
return containsKey(IAM_KEY);
}

public void putJwtAuthorizer(HttpApiV2JwtAuthorizer jwt) {
put(JWT_KEY, jwt);
}

public void putIamAuthorizer(HttpApiV2IamAuthorizer iam) {
put(IAM_KEY, iam);
}

public static class HttpApiV2AuthorizerDeserializer extends StdDeserializer<HttpApiV2AuthorizerMap> {
private static final long serialVersionUID = 42L;

Expand All @@ -64,18 +77,25 @@ public HttpApiV2AuthorizerDeserializer() {
}

@Override
public HttpApiV2AuthorizerMap deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
public HttpApiV2AuthorizerMap deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
HttpApiV2AuthorizerMap map = new HttpApiV2AuthorizerMap();
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
if (node.has(JWT_KEY)) {
HttpApiV2JwtAuthorizer authorizer = LambdaContainerHandler.getObjectMapper().treeToValue(node.get(JWT_KEY), HttpApiV2JwtAuthorizer.class);
HttpApiV2JwtAuthorizer authorizer = LambdaContainerHandler.getObjectMapper()
.treeToValue(node.get(JWT_KEY), HttpApiV2JwtAuthorizer.class);
map.putJwtAuthorizer(authorizer);
}
if (node.has(LAMBDA_KEY)) {
Map<String, Object> context = LambdaContainerHandler.getObjectMapper().treeToValue(node.get(LAMBDA_KEY),
TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, Object.class));
map.put(LAMBDA_KEY, context);
}
if (node.has(IAM_KEY)) {
HttpApiV2IamAuthorizer iam_authorizer = LambdaContainerHandler.getObjectMapper()
.treeToValue(node.get(IAM_KEY), HttpApiV2IamAuthorizer.class);
map.putIamAuthorizer(iam_authorizer);
}
// we ignore other, unknown values
return map;
}
Expand All @@ -89,14 +109,18 @@ public HttpApiV2AuthorizerSerializer() {
}

@Override
public void serialize(HttpApiV2AuthorizerMap httpApiV2AuthorizerMap, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
public void serialize(HttpApiV2AuthorizerMap httpApiV2AuthorizerMap, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
if (httpApiV2AuthorizerMap.isJwt()) {
jsonGenerator.writeObjectField(JWT_KEY, httpApiV2AuthorizerMap.getJwtAuthorizer());
}
if (httpApiV2AuthorizerMap.isLambda()) {
jsonGenerator.writeObjectField(LAMBDA_KEY, httpApiV2AuthorizerMap.getLambdaAuthorizerContext());
}
if (httpApiV2AuthorizerMap.isIam()) {
jsonGenerator.writeObjectField(IAM_KEY, httpApiV2AuthorizerMap.get(IAM_KEY));
}
jsonGenerator.writeEndObject();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.amazonaws.serverless.proxy.model;

public class HttpApiV2IamAuthorizer {
public String accessKey;
public String accountId;
public String callerId;
public String cognitoIdentity;
public String principalOrgId;
public String userArn;
public String userId;

public String getAccessKey() {
return accessKey;
}

public String getAccountId() {
return accountId;
}

public String getCallerId() {
return callerId;
}

public String getCognitoIdentity() {
return cognitoIdentity;
}

public String getPrincipalOrgId() {
return principalOrgId;
}

public String getUserArn() {
return userArn;
}

public String getUserId() {
return userId;
}

public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}

public void setAccountId(String accountId) {
this.accountId = accountId;
}

public void setCallerId(String callerId) {
this.callerId = callerId;
}

public void setCognitoIdentity(String cognitoIdentity) {
this.cognitoIdentity = cognitoIdentity;
}

public void setPrincipalOrgId(String principalOrgId) {
this.principalOrgId = principalOrgId;
}

public void setUserArn(String userArn) {
this.userArn = userArn;
}

public void setUserId(String userId) {
this.userId = userId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,55 @@ public class HttpApiV2ProxyRequestTest {
" \"isBase64Encoded\": false,\n" +
" \"stageVariables\": {\"stageVariable1\": \"value1\", \"stageVariable2\": \"value2\"}\n" +
" }\n";
private static final String IAM_AUTHORIZER = "{\n" +
" \"version\": \"2.0\",\n" +
" \"routeKey\": \"$default\",\n" +
" \"rawPath\": \"/my/path\",\n" +
" \"rawQueryString\": \"parameter1=value1&parameter1=value2&parameter2=value\",\n" +
" \"cookies\": [ \"cookie1\", \"cookie2\" ],\n" +
" \"headers\": {\n" +
" \"Header1\": \"value1\",\n" +
" \"Header2\": \"value2\"\n" +
" },\n" +
" \"queryStringParameters\": { \"parameter1\": \"value1,value2\", \"parameter2\": \"value\" },\n" +
" \"requestContext\": {\n" +
" \"accountId\": \"123456789012\",\n" +
" \"apiId\": \"api-id\",\n" +
" \"authorizer\": { \"iam\": {\n" +
" \"accessKey\": \"AKIAIOSFODNN7EXAMPLE\",\n" +
" \"accountId\": \"123456789012\",\n" +
" \"callerId\": \"AIDACKCEVSQ6C2EXAMPLE\",\n" +
" \"cognitoIdentity\": null,\n" +
" \"principalOrgId\": \"AIDACKCEVSQORGEXAMPLE\",\n" +
" \"userArn\": \"arn:aws:iam::111122223333:user/example-user\",\n" +
" \"userId\": \"AIDACOSFODNN7EXAMPLE2\"\n" +
" }" +
" },\n" +
" \"domainName\": \"id.execute-api.us-east-1.amazonaws.com\",\n" +
" \"domainPrefix\": \"id\",\n" +
" \"http\": {\n" +
" \"method\": \"POST\",\n" +
" \"path\": \"/my/path\",\n" +
" \"protocol\": \"HTTP/1.1\",\n" +
" \"sourceIp\": \"IP\",\n" +
" \"userAgent\": \"agent\"\n" +
" },\n" +
" \"requestId\": \"id\",\n" +
" \"routeKey\": \"$default\",\n" +
" \"stage\": \"$default\",\n" +
" \"time\": \"12/Mar/2020:19:03:58 +0000\",\n" +
" \"timeEpoch\": 1583348638390\n" +
" },\n" +
" \"body\": \"Hello from Lambda\",\n" +
" \"isBase64Encoded\": false,\n" +
" \"stageVariables\": {\"stageVariable1\": \"value1\", \"stageVariable2\": \"value2\"}\n" +
" }\n";

@Test
void deserialize_fromJsonString_authorizerPopulatedCorrectly() {
try {
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(BASE_PROXY_REQUEST, HttpApiV2ProxyRequest.class);
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(BASE_PROXY_REQUEST,
HttpApiV2ProxyRequest.class);
assertTrue(req.getRequestContext().getAuthorizer().getJwtAuthorizer().getClaims().containsKey("claim1"));
assertEquals(2, req.getRequestContext().getAuthorizer().getJwtAuthorizer().getScopes().size());
assertEquals(RequestSource.API_GATEWAY, req.getRequestSource());
Expand All @@ -146,10 +190,12 @@ void deserialize_fromJsonString_authorizerPopulatedCorrectly() {
@Test
void deserialize_fromJsonString_authorizerEmptyMap() {
try {
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(NO_AUTH_PROXY, HttpApiV2ProxyRequest.class);
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(NO_AUTH_PROXY,
HttpApiV2ProxyRequest.class);
assertNotNull(req.getRequestContext().getAuthorizer());
assertFalse(req.getRequestContext().getAuthorizer().isJwt());
assertFalse(req.getRequestContext().getAuthorizer().isLambda());
assertFalse(req.getRequestContext().getAuthorizer().isIam());
} catch (JsonProcessingException e) {
e.printStackTrace();
fail("Exception while parsing request" + e.getMessage());
Expand All @@ -159,7 +205,8 @@ void deserialize_fromJsonString_authorizerEmptyMap() {
@Test
void deserialize_fromJsonString_lambdaAuthorizer() {
try {
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(LAMBDA_AUTHORIZER, HttpApiV2ProxyRequest.class);
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(LAMBDA_AUTHORIZER,
HttpApiV2ProxyRequest.class);
assertNotNull(req.getRequestContext().getAuthorizer());
assertFalse(req.getRequestContext().getAuthorizer().isJwt());
assertTrue(req.getRequestContext().getAuthorizer().isLambda());
Expand All @@ -171,10 +218,38 @@ void deserialize_fromJsonString_lambdaAuthorizer() {
}
}

@Test
void deserialize_fromJsonString_iamAuthorizer() {
try {
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(IAM_AUTHORIZER,
HttpApiV2ProxyRequest.class);
assertNotNull(req.getRequestContext().getAuthorizer());
assertFalse(req.getRequestContext().getAuthorizer().isJwt());
assertFalse(req.getRequestContext().getAuthorizer().isLambda());
assertTrue(req.getRequestContext().getAuthorizer().isIam());
assertEquals("AKIAIOSFODNN7EXAMPLE",
req.getRequestContext().getAuthorizer().getIamAuthorizer().getAccessKey());
assertEquals("123456789012", req.getRequestContext().getAuthorizer().getIamAuthorizer().getAccountId());
assertEquals("AIDACKCEVSQ6C2EXAMPLE",
req.getRequestContext().getAuthorizer().getIamAuthorizer().getCallerId());
assertNull(req.getRequestContext().getAuthorizer().getIamAuthorizer().getCognitoIdentity());
assertEquals("AIDACKCEVSQORGEXAMPLE",
req.getRequestContext().getAuthorizer().getIamAuthorizer().getPrincipalOrgId());
assertEquals("arn:aws:iam::111122223333:user/example-user",
req.getRequestContext().getAuthorizer().getIamAuthorizer().getUserArn());
assertEquals("AIDACOSFODNN7EXAMPLE2",
req.getRequestContext().getAuthorizer().getIamAuthorizer().getUserId());
} catch (JsonProcessingException e) {
e.printStackTrace();
fail("Exception while parsing request" + e.getMessage());
}
}

@Test
void deserialize_fromJsonString_isBase64EncodedPopulates() {
try {
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(BASE_PROXY_REQUEST, HttpApiV2ProxyRequest.class);
HttpApiV2ProxyRequest req = LambdaContainerHandler.getObjectMapper().readValue(BASE_PROXY_REQUEST,
HttpApiV2ProxyRequest.class);
assertFalse(req.isBase64Encoded());
req = LambdaContainerHandler.getObjectMapper().readValue(NO_AUTH_PROXY, HttpApiV2ProxyRequest.class);
assertTrue(req.isBase64Encoded());
Expand Down Expand Up @@ -207,4 +282,4 @@ void serialize_toJsonString_authorizerPopulatesCorrectly() {
fail("Exception while serializing request" + e.getMessage());
}
}
}
}
Loading