Skip to content

Commit 8c08a8a

Browse files
authored
Merge pull request #25 from awslabs/cognito-user-pool
Cognito user pool support
2 parents 394bf66 + 8f0fcaa commit 8c08a8a

File tree

10 files changed

+437
-12
lines changed

10 files changed

+437
-12
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
language: java
2+
jdk:
3+
- oraclejdk8
4+
script: mvn install

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Serverless Java container
1+
# Serverless Java container [![Build Status](https://travis-ci.org/awslabs/aws-serverless-java-container.svg?branch=master)](https://travis-ci.org/awslabs/aws-serverless-java-container) [![Help](http://img.shields.io/badge/help-gitter-E91E63.svg?style=flat-square)](https://gitter.im/awslabs/aws-serverless-java-container)
22
The `aws-serverless-java-container` is collection of interfaces and their implementations that let you run Java application written with frameworks such as [Jersey](https://jersey.java.net/) or [Spark](http://sparkjava.com/) in [AWS Lambda](https://aws.amazon.com/lambda/).
33

44
The library contains a core artifact called `aws-serverless-java-container-core` that defines the interfaces and base classes required as well as default implementation of the Java servlet `HttpServletRequest` and `HttpServletResponse`.

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/jaxrs/AwsProxySecurityContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public Principal getUserPrincipal() {
7171
} else if (getAuthenticationScheme().equals(AUTH_SCHEME_AWS_IAM)) {
7272
return event.getRequestContext().getIdentity().getUserArn();
7373
} else if (getAuthenticationScheme().equals(AUTH_SCHEME_COGNITO_POOL)) {
74-
return event.getRequestContext().getIdentity().getCognitoIdentityId();
74+
return event.getRequestContext().getAuthorizer().getClaims().getSubject();
7575
}
7676

7777
return null;
@@ -90,7 +90,7 @@ public boolean isSecure() {
9090

9191

9292
public String getAuthenticationScheme() {
93-
if (event.getRequestContext().getIdentity().getCognitoAuthenticationType() != null) {
93+
if (event.getRequestContext().getAuthorizer() != null && event.getRequestContext().getAuthorizer().getClaims() != null && event.getRequestContext().getAuthorizer().getClaims().getSubject() != null) {
9494
return AUTH_SCHEME_COGNITO_POOL;
9595
} else if (event.getRequestContext().getAuthorizer() != null) {
9696
return AUTH_SCHEME_CUSTOM;

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/model/ApiGatewayAuthorizerContext.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,70 @@
1212
*/
1313
package com.amazonaws.serverless.proxy.internal.model;
1414

15+
import com.fasterxml.jackson.annotation.JsonAnyGetter;
16+
import com.fasterxml.jackson.annotation.JsonAnySetter;
17+
1518
import java.util.HashMap;
19+
import java.util.Map;
20+
1621

1722
/**
18-
* Custom authorizer context object for the API Gateway request context.
23+
* Context object used for custom authorizers and Cognito User Pool authorizers.
24+
* <p>
25+
* Custom authorizers populate the <code>principalId</code> field. All other custom values
26+
* returned by the authorizer are accessible via the <code>getContextValue</code> method.
27+
* </p>
28+
* <p>
29+
* Cognito User Pool authorizers populate the <pre>claims</pre> object.
30+
* </p>
1931
*/
20-
public class ApiGatewayAuthorizerContext extends HashMap<String, String> {
32+
public class ApiGatewayAuthorizerContext {
33+
34+
//-------------------------------------------------------------
35+
// Variables - Private
36+
//-------------------------------------------------------------
37+
38+
private Map<String, String> contextProperties = new HashMap<>();
39+
private String principalId;
40+
private CognitoAuthorizerClaims claims;
41+
42+
43+
//-------------------------------------------------------------
44+
// Methods - Public
45+
//-------------------------------------------------------------
46+
47+
@JsonAnyGetter
48+
public String getContextValue(String key) {
49+
return contextProperties.get(key);
50+
}
51+
52+
53+
@JsonAnySetter
54+
public void setContextValue(String key, String value) {
55+
contextProperties.put(key, value);
56+
}
57+
2158

2259
//-------------------------------------------------------------
2360
// Methods - Getter/Setter
2461
//-------------------------------------------------------------
2562

2663
public String getPrincipalId() {
27-
return get("principalId");
64+
return principalId;
2865
}
2966

3067

3168
public void setPrincipalId(String principalId) {
32-
put("principalId", principalId);
69+
this.principalId = principalId;
3370
}
3471

35-
public String getContextValue(String key) {
36-
return get(key);
72+
73+
public CognitoAuthorizerClaims getClaims() {
74+
return claims;
75+
}
76+
77+
78+
public void setClaims(CognitoAuthorizerClaims claims) {
79+
this.claims = claims;
3780
}
3881
}

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/model/AwsProxyRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import java.util.Map;
1818

1919
/**
20-
* Default implementation of the request object from an API GAteway AWS_PROXY integration
20+
* Default implementation of the request object from an API Gateway AWS_PROXY integration
2121
*/
2222
public class AwsProxyRequest {
2323

@@ -152,7 +152,7 @@ public boolean isBase64Encoded() {
152152
}
153153

154154

155-
public void setBase64Encoded(boolean base64Encoded) {
155+
public void setIsBase64Encoded(boolean base64Encoded) {
156156
isBase64Encoded = base64Encoded;
157157
}
158158
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5+
* with the License. A copy of the License is located at
6+
*
7+
* http://aws.amazon.com/apache2.0/
8+
*
9+
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
10+
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11+
* and limitations under the License.
12+
*/
13+
package com.amazonaws.serverless.proxy.internal.model;
14+
15+
16+
import com.fasterxml.jackson.annotation.JsonProperty;
17+
18+
import java.time.format.DateTimeFormatter;
19+
20+
21+
/**
22+
* This object represents the claims property in the authorizer context of a request. The claims object is normally populated
23+
* by a Cognito User Pool authorizer and contains the following fields:
24+
* <pre>
25+
* "claims": {
26+
* "sub": "42df3b02-29f1-4779-a3e5-eff92ff280b2",
27+
* "aud": "2k3no2j1rjjbqaskc4bk0ub29b",
28+
* "email_verified": "true",
29+
* "token_use": "id",
30+
* "auth_time": "1492467169",
31+
* "iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-2_Adx5ZHePg",
32+
* "cognito:username": "sapessi",
33+
* "expiration": "Mon Apr 17 23:12:49 UTC 2017",
34+
* "issuedAt": "Mon Apr 17 22:12:49 UTC 2017",
35+
* "email": "[email protected]"
36+
* }
37+
* </pre>
38+
*/
39+
public class CognitoAuthorizerClaims {
40+
41+
//-------------------------------------------------------------
42+
// Variables - Private
43+
//-------------------------------------------------------------
44+
45+
@JsonProperty(value = "sub")
46+
private String subject;
47+
@JsonProperty(value = "aud")
48+
private String audience;
49+
@JsonProperty(value = "iss")
50+
private String issuer;
51+
@JsonProperty(value = "token_use")
52+
private String tokenUse;
53+
@JsonProperty(value = "cognito:username")
54+
private String username;
55+
private String email;
56+
@JsonProperty(value = "email_verified")
57+
private boolean emailVerified;
58+
@JsonProperty(value = "auth_time")
59+
private Long authTime;
60+
@JsonProperty(value = "exp")
61+
private String expiration;
62+
@JsonProperty(value = "iat")
63+
private String issuedAt;
64+
65+
66+
//-------------------------------------------------------------
67+
// Methods - Getter/Setter
68+
//-------------------------------------------------------------
69+
70+
public String getSubject() { return this.subject; }
71+
72+
73+
public void setSubject(String subject) {
74+
this.subject = subject;
75+
}
76+
77+
78+
public String getAudience() {
79+
return audience;
80+
}
81+
82+
83+
public void setAudience(String audience) {
84+
this.audience = audience;
85+
}
86+
87+
88+
public String getIssuer() {
89+
return issuer;
90+
}
91+
92+
93+
public void setIssuer(String issuer) {
94+
this.issuer = issuer;
95+
}
96+
97+
98+
public String getTokenUse() {
99+
return tokenUse;
100+
}
101+
102+
103+
public void setTokenUse(String tokenUse) {
104+
this.tokenUse = tokenUse;
105+
}
106+
107+
108+
public String getUsername() {
109+
return username;
110+
}
111+
112+
113+
public void setUsername(String username) {
114+
this.username = username;
115+
}
116+
117+
118+
public String getEmail() {
119+
return email;
120+
}
121+
122+
123+
public void setEmail(String email) {
124+
this.email = email;
125+
}
126+
127+
128+
public boolean isEmailVerified() {
129+
return emailVerified;
130+
}
131+
132+
133+
public void setEmailVerified(boolean emailVerified) {
134+
this.emailVerified = emailVerified;
135+
}
136+
137+
138+
public Long getAuthTime() {
139+
return authTime;
140+
}
141+
142+
143+
public void setAuthTime(Long authTime) {
144+
this.authTime = authTime;
145+
}
146+
147+
148+
public String getExpiration() {
149+
return expiration;
150+
}
151+
152+
153+
public void setExpiration(String expiration) {
154+
this.expiration = expiration;
155+
}
156+
157+
158+
public String getIssuedAt() {
159+
return issuedAt;
160+
}
161+
162+
163+
public void setIssuedAt(String issuedAt) {
164+
this.issuedAt = issuedAt;
165+
}
166+
}

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletRequest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ protected List<Map.Entry<String, String>> parseHeaderValue(String headerValue) {
280280
if (headerValue == null) {
281281
return values;
282282
}
283+
283284
for (String kv : headerValue.split(HEADER_VALUE_SEPARATOR)) {
284285
String[] kvSplit = kv.split(HEADER_KEY_VALUE_SEPARATOR);
285286

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/testutils/AwsProxyRequestBuilder.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@
1616
import com.amazonaws.serverless.proxy.internal.model.ApiGatewayRequestContext;
1717
import com.amazonaws.serverless.proxy.internal.model.ApiGatewayRequestIdentity;
1818
import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
19+
import com.amazonaws.serverless.proxy.internal.model.CognitoAuthorizerClaims;
20+
1921
import com.fasterxml.jackson.core.JsonProcessingException;
2022
import com.fasterxml.jackson.databind.ObjectMapper;
2123

2224
import javax.ws.rs.core.HttpHeaders;
2325
import javax.ws.rs.core.MediaType;
26+
27+
import java.io.File;
28+
import java.io.IOException;
2429
import java.util.HashMap;
2530

2631
/**
@@ -156,14 +161,20 @@ public AwsProxyRequestBuilder authorizerContextValue(String key, String value) {
156161
if (this.request.getRequestContext().getAuthorizer() == null) {
157162
this.request.getRequestContext().setAuthorizer(new ApiGatewayAuthorizerContext());
158163
}
159-
this.request.getRequestContext().getAuthorizer().put(key, value);
164+
this.request.getRequestContext().getAuthorizer().setContextValue(key, value);
160165
return this;
161166
}
162167

163168

164169
public AwsProxyRequestBuilder cognitoUserPool(String identityId) {
165170
this.request.getRequestContext().getIdentity().setCognitoAuthenticationType("POOL");
166171
this.request.getRequestContext().getIdentity().setCognitoIdentityId(identityId);
172+
if (this.request.getRequestContext().getAuthorizer() == null) {
173+
this.request.getRequestContext().setAuthorizer(new ApiGatewayAuthorizerContext());
174+
}
175+
this.request.getRequestContext().getAuthorizer().setClaims(new CognitoAuthorizerClaims());
176+
this.request.getRequestContext().getAuthorizer().getClaims().setSubject(identityId);
177+
167178
return this;
168179
}
169180

@@ -209,6 +220,18 @@ public AwsProxyRequestBuilder serverName(String serverName) {
209220
return this;
210221
}
211222

223+
public AwsProxyRequestBuilder fromJsonString(String jsonContent)
224+
throws IOException {
225+
request = mapper.readValue(jsonContent, AwsProxyRequest.class);
226+
return this;
227+
}
228+
229+
public AwsProxyRequestBuilder fromJsonPath(String filePath)
230+
throws IOException {
231+
request = mapper.readValue(new File(filePath), AwsProxyRequest.class);
232+
return this;
233+
}
234+
212235
public AwsProxyRequest build() {
213236
return this.request;
214237
}

0 commit comments

Comments
 (0)