use of com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent in project di-authentication-api by alphagov.
the class AuthorisationHandler method handleRequest.
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
return isWarming(input).orElseGet(() -> {
var persistentSessionId = authorizationService.getExistingOrCreateNewPersistentSessionId(input.getHeaders());
var ipAddress = IpAddressHelper.extractIpAddress(input);
auditService.submitAuditEvent(OidcAuditableEvent.AUTHORISATION_REQUEST_RECEIVED, context.getAwsRequestId(), AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN, ipAddress, AuditService.UNKNOWN, persistentSessionId);
attachLogFieldToLogs(PERSISTENT_SESSION_ID, persistentSessionId);
attachLogFieldToLogs(AWS_REQUEST_ID, context.getAwsRequestId());
LOG.info("Received authentication request");
Map<String, List<String>> queryStringParameters;
AuthenticationRequest authRequest;
try {
queryStringParameters = input.getQueryStringParameters().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> List.of(entry.getValue())));
authRequest = AuthenticationRequest.parse(queryStringParameters);
} catch (ParseException e) {
if (e.getRedirectionURI() == null) {
LOG.warn("Authentication request could not be parsed: redirect URI or Client ID is missing from auth request");
throw new RuntimeException("Redirect URI or ClientID is missing from auth request", e);
}
LOG.warn("Authentication request could not be parsed", e);
return generateErrorResponse(e.getRedirectionURI(), e.getState(), e.getResponseMode(), e.getErrorObject(), context, ipAddress, persistentSessionId);
} catch (NullPointerException e) {
LOG.warn("No query string parameters are present in the Authentication request", e);
throw new RuntimeException("No query string parameters are present in the Authentication request", e);
}
var error = authorizationService.validateAuthRequest(authRequest);
return error.map(e -> generateErrorResponse(authRequest.getRedirectionURI(), authRequest.getState(), authRequest.getResponseMode(), e, context, ipAddress, persistentSessionId)).orElseGet(() -> getOrCreateSessionAndRedirect(queryStringParameters, sessionService.getSessionFromSessionCookie(input.getHeaders()), authRequest, context, ipAddress, persistentSessionId));
});
}
use of com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent in project di-authentication-api by alphagov.
the class TokenHandlerTest method shouldReturn200ForSuccessfulTokenRequest.
@ParameterizedTest
@MethodSource("validVectorValues")
public void shouldReturn200ForSuccessfulTokenRequest(String vectorValue) throws JOSEException {
KeyPair keyPair = generateRsaKeyPair();
UserProfile userProfile = generateUserProfile();
SignedJWT signedJWT = generateIDToken(CLIENT_ID, PUBLIC_SUBJECT, "issuer-url", new ECKeyGenerator(Curve.P_256).algorithm(JWSAlgorithm.ES256).generate());
OIDCTokenResponse tokenResponse = new OIDCTokenResponse(new OIDCTokens(signedJWT, accessToken, refreshToken));
PrivateKeyJWT privateKeyJWT = generatePrivateKeyJWT(keyPair.getPrivate());
ClientRegistry clientRegistry = generateClientRegistry(keyPair);
when(tokenService.validateTokenRequestParams(anyString())).thenReturn(Optional.empty());
when(clientService.getClient(eq(CLIENT_ID))).thenReturn(Optional.of(clientRegistry));
when(tokenService.validatePrivateKeyJWT(anyString(), eq(clientRegistry.getPublicKey()), eq(BASE_URI), eq(CLIENT_ID))).thenReturn(Optional.empty());
String authCode = new AuthorizationCode().toString();
when(authorisationCodeService.getExchangeDataForCode(authCode)).thenReturn(Optional.of(new AuthCodeExchangeData().setEmail(TEST_EMAIL).setClientSessionId(CLIENT_SESSION_ID)));
AuthenticationRequest authenticationRequest = generateAuthRequest(JsonArrayHelper.jsonArrayOf(vectorValue));
VectorOfTrust vtr = VectorOfTrust.parseFromAuthRequestAttribute(authenticationRequest.getCustomParameter("vtr"));
when(clientSessionService.getClientSession(CLIENT_SESSION_ID)).thenReturn(new ClientSession(authenticationRequest.toParameters(), LocalDateTime.now(), vtr));
when(dynamoService.getUserProfileByEmail(eq(TEST_EMAIL))).thenReturn(userProfile);
when(tokenService.generateTokenResponse(CLIENT_ID, INTERNAL_SUBJECT, SCOPES, Map.of("nonce", NONCE), PUBLIC_SUBJECT, vtr.retrieveVectorOfTrustForToken(), userProfile.getClientConsent(), clientRegistry.isConsentRequired(), null)).thenReturn(tokenResponse);
APIGatewayProxyResponseEvent result = generateApiGatewayRequest(privateKeyJWT, authCode);
assertThat(result, hasStatus(200));
assertTrue(result.getBody().contains(refreshToken.getValue()));
assertTrue(result.getBody().contains(accessToken.getValue()));
}
use of com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent in project di-authentication-api by alphagov.
the class TokenHandlerTest method shouldReturn200ForSuccessfulRefreshTokenRequest.
@Test
public void shouldReturn200ForSuccessfulRefreshTokenRequest() throws JOSEException, JsonProcessingException {
SignedJWT signedRefreshToken = createSignedRefreshToken();
KeyPair keyPair = generateRsaKeyPair();
RefreshToken refreshToken = new RefreshToken(signedRefreshToken.serialize());
OIDCTokenResponse tokenResponse = new OIDCTokenResponse(new OIDCTokens(accessToken, refreshToken));
PrivateKeyJWT privateKeyJWT = generatePrivateKeyJWT(keyPair.getPrivate());
ClientRegistry clientRegistry = generateClientRegistry(keyPair);
when(tokenService.validateTokenRequestParams(anyString())).thenReturn(Optional.empty());
when(clientService.getClient(eq(CLIENT_ID))).thenReturn(Optional.of(clientRegistry));
when(tokenService.validatePrivateKeyJWT(anyString(), eq(clientRegistry.getPublicKey()), eq(BASE_URI), eq(CLIENT_ID))).thenReturn(Optional.empty());
when(tokenValidationService.validateRefreshTokenSignatureAndExpiry(refreshToken)).thenReturn(true);
when(tokenValidationService.validateRefreshTokenScopes(SCOPES.toStringList(), SCOPES.toStringList())).thenReturn(true);
RefreshTokenStore tokenStore = new RefreshTokenStore(singletonList(refreshToken.getValue()), INTERNAL_SUBJECT.getValue());
String redisKey = REFRESH_TOKEN_PREFIX + CLIENT_ID + "." + PUBLIC_SUBJECT.getValue();
String tokenStoreString = new ObjectMapper().writeValueAsString(tokenStore);
when(redisConnectionService.getValue(redisKey)).thenReturn(tokenStoreString);
when(tokenService.generateRefreshTokenResponse(eq(CLIENT_ID), eq(INTERNAL_SUBJECT), eq(SCOPES.toStringList()), eq(PUBLIC_SUBJECT))).thenReturn(tokenResponse);
APIGatewayProxyResponseEvent result = generateApiGatewayRefreshRequest(privateKeyJWT, refreshToken.getValue());
assertThat(result, hasStatus(200));
assertTrue(result.getBody().contains(refreshToken.getValue()));
assertTrue(result.getBody().contains(accessToken.getValue()));
verify(redisConnectionService, times(1)).deleteValue(redisKey);
}
use of com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent in project di-authentication-api by alphagov.
the class AuthCodeHandlerTest method shouldGenerateSuccessfulAuthResponseAndUpliftAsNecessary.
@ParameterizedTest
@MethodSource("upliftTestParameters")
void shouldGenerateSuccessfulAuthResponseAndUpliftAsNecessary(CredentialTrustLevel initialLevel, CredentialTrustLevel requestedLevel, CredentialTrustLevel finalLevel) throws ClientNotFoundException, URISyntaxException, JsonProcessingException {
AuthorizationCode authorizationCode = new AuthorizationCode();
AuthenticationRequest authRequest = generateValidSessionAndAuthRequest(requestedLevel);
session.setCurrentCredentialStrength(initialLevel).setNewAccount(NEW);
AuthenticationSuccessResponse authSuccessResponse = new AuthenticationSuccessResponse(authRequest.getRedirectionURI(), authorizationCode, null, null, authRequest.getState(), null, authRequest.getResponseMode());
when(authorizationService.isClientRedirectUriValid(eq(CLIENT_ID), eq(REDIRECT_URI))).thenReturn(true);
when(authorisationCodeService.generateAuthorisationCode(eq(CLIENT_SESSION_ID), eq(EMAIL))).thenReturn(authorizationCode);
when(authorizationService.generateSuccessfulAuthResponse(any(AuthenticationRequest.class), any(AuthorizationCode.class))).thenReturn(authSuccessResponse);
APIGatewayProxyResponseEvent response = generateApiRequest();
assertThat(response, hasStatus(200));
AuthCodeResponse authCodeResponse = new ObjectMapper().readValue(response.getBody(), AuthCodeResponse.class);
assertThat(authCodeResponse.getLocation(), equalTo(authSuccessResponse.toURI().toString()));
assertThat(session.getCurrentCredentialStrength(), equalTo(finalLevel));
verify(sessionService).save(session.setAuthenticated(true));
verify(auditService).submitAuditEvent(OidcAuditableEvent.AUTH_CODE_ISSUED, "aws-session-id", SESSION_ID, CLIENT_ID.getValue(), AuditService.UNKNOWN, EMAIL, "123.123.123.123", AuditService.UNKNOWN, PERSISTENT_SESSION_ID);
verify(cloudwatchMetricsService).incrementCounter("SignIn", Map.of("Account", "NEW", "Environment", "unit-test", "Client", CLIENT_ID.getValue()));
}
use of com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent in project di-authentication-api by alphagov.
the class IdentityHandlerTest method shouldReturn401WhenBearerTokenIsNotParseable.
@Test
void shouldReturn401WhenBearerTokenIsNotParseable() throws AccessTokenException {
APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
event.setHeaders(Map.of("Authorization", "this-is-not-a-valid-token"));
AccessTokenException accessTokenException = new AccessTokenException("Unable to parse AccessToken", INVALID_TOKEN);
when(accessTokenService.parse("this-is-not-a-valid-token", true)).thenThrow(accessTokenException);
APIGatewayProxyResponseEvent result = handler.handleRequest(event, context);
assertThat(result, hasStatus(401));
assertEquals(INVALID_TOKEN_RESPONSE, result.getMultiValueHeaders());
}
Aggregations