Search in sources :

Example 1 with AuthCodeResponse

use of uk.gov.di.authentication.oidc.entity.AuthCodeResponse in project di-authentication-api by alphagov.

the class AuthCodeHandler method handleRequest.

@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
    return isWarming(input).orElseGet(() -> {
        Session session = sessionService.getSessionFromRequestHeaders(input.getHeaders()).orElse(null);
        if (Objects.isNull(session)) {
            return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1000);
        }
        String clientSessionId = getHeaderValueFromHeaders(input.getHeaders(), CLIENT_SESSION_ID_HEADER, configurationService.getHeadersCaseInsensitive());
        if (Objects.isNull(clientSessionId)) {
            return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1018);
        }
        attachSessionIdToLogs(session);
        attachLogFieldToLogs(CLIENT_SESSION_ID, clientSessionId);
        LOG.info("Processing request");
        AuthenticationRequest authenticationRequest;
        ClientSession clientSession;
        try {
            clientSession = clientSessionService.getClientSessionFromRequestHeaders(input.getHeaders()).orElse(null);
            if (Objects.isNull(clientSession)) {
                LOG.info("ClientSession not found");
                return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1018);
            }
            authenticationRequest = AuthenticationRequest.parse(clientSession.getAuthRequestParams());
        } 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", e);
                throw new RuntimeException("Redirect URI or Client ID is missing from auth request", e);
            }
            AuthenticationErrorResponse errorResponse = authorizationService.generateAuthenticationErrorResponse(e.getRedirectionURI(), e.getState(), e.getResponseMode(), e.getErrorObject());
            LOG.warn("Authentication request could not be parsed", e);
            return generateResponse(new AuthCodeResponse(errorResponse.toURI().toString()));
        }
        try {
            if (!authorizationService.isClientRedirectUriValid(authenticationRequest.getClientID(), authenticationRequest.getRedirectionURI())) {
                return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1016);
            }
            VectorOfTrust requestedVectorOfTrust = clientSession.getEffectiveVectorOfTrust();
            if (isNull(session.getCurrentCredentialStrength()) || requestedVectorOfTrust.getCredentialTrustLevel().compareTo(session.getCurrentCredentialStrength()) > 0) {
                session.setCurrentCredentialStrength(requestedVectorOfTrust.getCredentialTrustLevel());
            }
            AuthorizationCode authCode = authorisationCodeService.generateAuthorisationCode(clientSessionId, session.getEmailAddress());
            AuthenticationSuccessResponse authenticationResponse = authorizationService.generateSuccessfulAuthResponse(authenticationRequest, authCode);
            LOG.info("Successfully processed request");
            cloudwatchMetricsService.incrementCounter("SignIn", Map.of("Account", session.isNewAccount().name(), "Environment", configurationService.getEnvironment(), "Client", authenticationRequest.getClientID().getValue()));
            sessionService.save(session.setAuthenticated(true).setNewAccount(EXISTING));
            auditService.submitAuditEvent(OidcAuditableEvent.AUTH_CODE_ISSUED, context.getAwsRequestId(), session.getSessionId(), authenticationRequest.getClientID().getValue(), AuditService.UNKNOWN, session.getEmailAddress(), IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders()));
            return generateResponse(new AuthCodeResponse(authenticationResponse.toURI().toString()));
        } catch (ClientNotFoundException e) {
            AuthenticationErrorResponse errorResponse = authorizationService.generateAuthenticationErrorResponse(authenticationRequest, OAuth2Error.INVALID_CLIENT);
            return generateResponse(new AuthCodeResponse(errorResponse.toURI().toString()));
        } catch (URISyntaxException e) {
            return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1016);
        }
    });
}
Also used : AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) AuthCodeResponse(uk.gov.di.authentication.oidc.entity.AuthCodeResponse) AuthenticationErrorResponse(com.nimbusds.openid.connect.sdk.AuthenticationErrorResponse) ClientNotFoundException(uk.gov.di.authentication.shared.exceptions.ClientNotFoundException) VectorOfTrust(uk.gov.di.authentication.shared.entity.VectorOfTrust) URISyntaxException(java.net.URISyntaxException) AuthenticationSuccessResponse(com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse) ClientSession(uk.gov.di.authentication.shared.entity.ClientSession) ParseException(com.nimbusds.oauth2.sdk.ParseException) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) Session(uk.gov.di.authentication.shared.entity.Session) ClientSession(uk.gov.di.authentication.shared.entity.ClientSession)

Example 2 with AuthCodeResponse

use of uk.gov.di.authentication.oidc.entity.AuthCodeResponse 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()));
}
Also used : AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) AuthCodeResponse(uk.gov.di.authentication.oidc.entity.AuthCodeResponse) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) APIGatewayProxyResponseEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent) AuthenticationSuccessResponse(com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 3 with AuthCodeResponse

use of uk.gov.di.authentication.oidc.entity.AuthCodeResponse in project di-authentication-api by alphagov.

the class AuthCodeHandlerTest method shouldGenerateSuccessfulAuthResponseAndUpliftAsNecessary.

@ParameterizedTest
@MethodSource("upliftTestParameters")
void shouldGenerateSuccessfulAuthResponseAndUpliftAsNecessary(CredentialTrustLevel initialLevel, CredentialTrustLevel requestedLevel, CredentialTrustLevel finalLevel, boolean docAppJourney) throws ClientNotFoundException, URISyntaxException, Json.JsonException, JOSEException {
    AuthorizationCode authorizationCode = new AuthorizationCode();
    AuthenticationRequest authRequest = generateValidSessionAndAuthRequest(requestedLevel, docAppJourney);
    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(CLIENT_SESSION_ID, EMAIL, clientSession)).thenReturn(authorizationCode);
    when(authorizationService.generateSuccessfulAuthResponse(any(AuthenticationRequest.class), any(AuthorizationCode.class), any(URI.class), any(State.class))).thenReturn(authSuccessResponse);
    APIGatewayProxyResponseEvent response = generateApiRequest();
    assertThat(response, hasStatus(200));
    AuthCodeResponse authCodeResponse = objectMapper.readValue(response.getBody(), AuthCodeResponse.class);
    assertThat(authCodeResponse.getLocation(), equalTo(authSuccessResponse.toURI().toString()));
    assertThat(session.getCurrentCredentialStrength(), equalTo(finalLevel));
    assertThat(session.isAuthenticated(), not(equalTo(docAppJourney)));
    verify(sessionService, times(docAppJourney ? 0 : 1)).save(session);
    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()));
}
Also used : AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) AuthCodeResponse(uk.gov.di.authentication.oidc.entity.AuthCodeResponse) State(com.nimbusds.oauth2.sdk.id.State) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) APIGatewayProxyResponseEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent) URI(java.net.URI) AuthenticationSuccessResponse(com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 4 with AuthCodeResponse

use of uk.gov.di.authentication.oidc.entity.AuthCodeResponse in project di-authentication-api by alphagov.

the class AuthCodeHandlerTest method shouldGenerateErrorResponseIfUnableToParseAuthRequest.

@Test
void shouldGenerateErrorResponseIfUnableToParseAuthRequest() throws Json.JsonException {
    AuthenticationErrorResponse authenticationErrorResponse = new AuthenticationErrorResponse(REDIRECT_URI, OAuth2Error.INVALID_REQUEST, null, null);
    when(authorizationService.generateAuthenticationErrorResponse(eq(REDIRECT_URI), isNull(), any(ResponseMode.class), eq(OAuth2Error.INVALID_REQUEST))).thenReturn(authenticationErrorResponse);
    Map<String, List<String>> customParams = new HashMap<>();
    customParams.put("redirect_uri", singletonList("http://localhost/redirect"));
    customParams.put("client_id", singletonList(new ClientID().toString()));
    generateValidSession(customParams, MEDIUM_LEVEL, false);
    APIGatewayProxyResponseEvent response = generateApiRequest();
    assertThat(response, hasStatus(200));
    AuthCodeResponse authCodeResponse = objectMapper.readValue(response.getBody(), AuthCodeResponse.class);
    assertThat(authCodeResponse.getLocation(), equalTo("http://localhost/redirect?error=invalid_request&error_description=Invalid+request"));
    verifyNoInteractions(auditService);
}
Also used : AuthCodeResponse(uk.gov.di.authentication.oidc.entity.AuthCodeResponse) AuthenticationErrorResponse(com.nimbusds.openid.connect.sdk.AuthenticationErrorResponse) ResponseMode(com.nimbusds.oauth2.sdk.ResponseMode) HashMap(java.util.HashMap) ClientID(com.nimbusds.oauth2.sdk.id.ClientID) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) APIGatewayProxyResponseEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 5 with AuthCodeResponse

use of uk.gov.di.authentication.oidc.entity.AuthCodeResponse in project di-authentication-api by alphagov.

the class AuthCodeIntegrationTest method shouldReturn302WithSuccessfulAuthorisationResponse.

@Test
public void shouldReturn302WithSuccessfulAuthorisationResponse() throws IOException, Json.JsonException {
    String sessionId = "some-session-id";
    String clientSessionId = "some-client-session-id";
    KeyPair keyPair = KeyPairHelper.GENERATE_RSA_KEY_PAIR();
    redis.createSession(sessionId);
    redis.addAuthRequestToSession(clientSessionId, sessionId, generateAuthRequest().toParameters());
    setUpDynamo(keyPair);
    Map<String, String> headers = new HashMap<>();
    headers.put("Session-Id", sessionId);
    headers.put("X-API-Key", FRONTEND_API_KEY);
    headers.put("Client-Session-Id", clientSessionId);
    var response = makeRequest(Optional.empty(), headers, Map.of());
    assertThat(response, hasStatus(200));
    AuthCodeResponse authCodeResponse = objectMapper.readValue(response.getBody(), AuthCodeResponse.class);
    assertThat(authCodeResponse.getLocation(), startsWith("https://di-auth-stub-relying-party-build.london.cloudapps.digital/?code="));
    assertEventTypesReceived(auditTopic, List.of(AUTH_CODE_ISSUED));
}
Also used : KeyPair(java.security.KeyPair) AuthCodeResponse(uk.gov.di.authentication.oidc.entity.AuthCodeResponse) HashMap(java.util.HashMap) Test(org.junit.jupiter.api.Test) ApiGatewayHandlerIntegrationTest(uk.gov.di.authentication.sharedtest.basetest.ApiGatewayHandlerIntegrationTest)

Aggregations

AuthCodeResponse (uk.gov.di.authentication.oidc.entity.AuthCodeResponse)7 AuthenticationRequest (com.nimbusds.openid.connect.sdk.AuthenticationRequest)5 APIGatewayProxyResponseEvent (com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent)4 AuthorizationCode (com.nimbusds.oauth2.sdk.AuthorizationCode)4 AuthenticationErrorResponse (com.nimbusds.openid.connect.sdk.AuthenticationErrorResponse)4 AuthenticationSuccessResponse (com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse)4 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)4 State (com.nimbusds.oauth2.sdk.id.State)3 URI (java.net.URI)3 Test (org.junit.jupiter.api.Test)3 ParseException (com.nimbusds.oauth2.sdk.ParseException)2 HashMap (java.util.HashMap)2 MethodSource (org.junit.jupiter.params.provider.MethodSource)2 ClientSession (uk.gov.di.authentication.shared.entity.ClientSession)2 Session (uk.gov.di.authentication.shared.entity.Session)2 VectorOfTrust (uk.gov.di.authentication.shared.entity.VectorOfTrust)2 ClientNotFoundException (uk.gov.di.authentication.shared.exceptions.ClientNotFoundException)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 ResponseMode (com.nimbusds.oauth2.sdk.ResponseMode)1 ClientID (com.nimbusds.oauth2.sdk.id.ClientID)1