Search in sources :

Example 6 with Subject

use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.

the class UserInfoIntegrationTest method shouldCallUserInfoWithAccessTokenAndReturn200.

@Test
public void shouldCallUserInfoWithAccessTokenAndReturn200() throws JsonProcessingException {
    Subject internalSubject = new Subject();
    Subject publicSubject = new Subject();
    LocalDateTime localDateTime = LocalDateTime.now().plusMinutes(10);
    Date expiryDate = Date.from(localDateTime.atZone(ZoneId.of("UTC")).toInstant());
    List<String> scopes = new ArrayList<>();
    scopes.add("email");
    scopes.add("phone");
    scopes.add("openid");
    JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim("scope", scopes).issuer("issuer-id").expirationTime(expiryDate).issueTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant())).claim("client_id", "client-id-one").subject(publicSubject.getValue()).jwtID(UUID.randomUUID().toString()).build();
    SignedJWT signedJWT = tokenSigner.signJwt(claimsSet);
    AccessToken accessToken = new BearerAccessToken(signedJWT.serialize());
    AccessTokenStore accessTokenStore = new AccessTokenStore(accessToken.getValue(), internalSubject.getValue());
    String accessTokenStoreString = new ObjectMapper().writeValueAsString(accessTokenStore);
    redis.addToRedis(ACCESS_TOKEN_PREFIX + CLIENT_ID + "." + publicSubject, accessTokenStoreString, 300L);
    setUpDynamo(internalSubject);
    var response = makeRequest(Optional.empty(), Map.of("Authorization", accessToken.toAuthorizationHeader()), Map.of());
    assertThat(response, hasStatus(200));
    UserInfo expectedUserInfoResponse = new UserInfo(publicSubject);
    expectedUserInfoResponse.setEmailAddress(TEST_EMAIL_ADDRESS);
    expectedUserInfoResponse.setEmailVerified(true);
    expectedUserInfoResponse.setPhoneNumber(FORMATTED_PHONE_NUMBER);
    expectedUserInfoResponse.setPhoneNumberVerified(true);
    assertThat(response.getBody(), equalTo(expectedUserInfoResponse.toJSONString()));
    assertNoAuditEventsReceived(auditTopic);
}
Also used : LocalDateTime(java.time.LocalDateTime) ArrayList(java.util.ArrayList) UserInfo(com.nimbusds.openid.connect.sdk.claims.UserInfo) SignedJWT(com.nimbusds.jwt.SignedJWT) Subject(com.nimbusds.oauth2.sdk.id.Subject) Date(java.util.Date) AccessTokenStore(uk.gov.di.authentication.shared.entity.AccessTokenStore) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) AccessToken(com.nimbusds.oauth2.sdk.token.AccessToken) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Test(org.junit.jupiter.api.Test) ApiGatewayHandlerIntegrationTest(uk.gov.di.authentication.sharedtest.basetest.ApiGatewayHandlerIntegrationTest)

Example 7 with Subject

use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.

the class ResetPasswordRequestHandlerTest method shouldReturn200AndPutMessageOnQueueForAValidRequest.

@Test
void shouldReturn200AndPutMessageOnQueueForAValidRequest() throws JsonProcessingException {
    String persistentId = "some-persistent-id-value";
    Map<String, String> headers = new HashMap<>();
    headers.put(PersistentIdHelper.PERSISTENT_ID_HEADER_NAME, persistentId);
    headers.put("Session-Id", session.getSessionId());
    Subject subject = new Subject("subject_1");
    when(validationService.validateEmailAddress(eq(TEST_EMAIL_ADDRESS))).thenReturn(Optional.empty());
    when(authenticationService.getSubjectFromEmail(TEST_EMAIL_ADDRESS)).thenReturn(subject);
    when(resetPasswordService.buildResetPasswordLink(TEST_SIX_DIGIT_CODE, session.getSessionId(), persistentId)).thenReturn(TEST_RESET_PASSWORD_LINK);
    NotifyRequest notifyRequest = new NotifyRequest(TEST_EMAIL_ADDRESS, RESET_PASSWORD, TEST_RESET_PASSWORD_LINK);
    ObjectMapper objectMapper = new ObjectMapper();
    String serialisedRequest = objectMapper.writeValueAsString(notifyRequest);
    usingValidSession();
    APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
    event.setRequestContext(contextWithSourceIp("123.123.123.123"));
    event.setHeaders(headers);
    event.setBody(format("{ \"email\": \"%s\" }", TEST_EMAIL_ADDRESS));
    APIGatewayProxyResponseEvent result = handler.handleRequest(event, context);
    assertEquals(204, result.getStatusCode());
    verify(awsSqsClient).send(serialisedRequest);
    verify(codeStorageService).savePasswordResetCode(subject.getValue(), TEST_SIX_DIGIT_CODE, CODE_EXPIRY_TIME, RESET_PASSWORD);
    verify(sessionService).save(argThat(this::isSessionWithEmailSent));
    verify(auditService).submitAuditEvent(FrontendAuditableEvent.PASSWORD_RESET_REQUESTED, context.getAwsRequestId(), session.getSessionId(), AuditService.UNKNOWN, AuditService.UNKNOWN, TEST_EMAIL_ADDRESS, "123.123.123.123", AuditService.UNKNOWN, persistentId);
}
Also used : APIGatewayProxyRequestEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent) HashMap(java.util.HashMap) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) NotifyRequest(uk.gov.di.authentication.shared.entity.NotifyRequest) APIGatewayProxyResponseEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent) Subject(com.nimbusds.oauth2.sdk.id.Subject) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Test(org.junit.jupiter.api.Test)

Example 8 with Subject

use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.

the class TokenService method generateIDToken.

private SignedJWT generateIDToken(String clientId, Subject publicSubject, Map<String, Object> additionalTokenClaims, AccessTokenHash accessTokenHash, String vot) {
    attachLogFieldToLogs(CLIENT_ID, clientId);
    LOG.info("Generating IdToken");
    URI trustMarkUri = buildURI(configService.getBaseURL().get(), "/trustmark");
    LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(configService.getIDTokenExpiry());
    Date expiryDate = Date.from(localDateTime.atZone(ZoneId.of("UTC")).toInstant());
    IDTokenClaimsSet idTokenClaims = new IDTokenClaimsSet(new Issuer(configService.getBaseURL().get()), publicSubject, List.of(new Audience(clientId)), expiryDate, new Date());
    idTokenClaims.setAccessTokenHash(accessTokenHash);
    idTokenClaims.putAll(additionalTokenClaims);
    idTokenClaims.setClaim("vot", vot);
    idTokenClaims.setClaim("vtm", trustMarkUri.toString());
    try {
        return generateSignedJWT(idTokenClaims.toJWTClaimsSet());
    } catch (com.nimbusds.oauth2.sdk.ParseException e) {
        LOG.error("Error when trying to parse IDTokenClaims to JWTClaimSet", e);
        throw new RuntimeException(e);
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) Issuer(com.nimbusds.oauth2.sdk.id.Issuer) Audience(com.nimbusds.oauth2.sdk.id.Audience) IDTokenClaimsSet(com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet) ParseException(com.nimbusds.oauth2.sdk.ParseException) URI(java.net.URI) ConstructUriHelper.buildURI(uk.gov.di.authentication.shared.helpers.ConstructUriHelper.buildURI) Date(java.util.Date)

Example 9 with Subject

use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.

the class UpdateEmailHandler method handleRequest.

@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
    return isWarming(input).orElseGet(() -> {
        String sessionId = RequestHeaderHelper.getHeaderValueOrElse(input.getHeaders(), SESSION_ID_HEADER, "");
        attachSessionIdToLogs(sessionId);
        LOG.info("UpdateEmailHandler received request");
        try {
            UpdateEmailRequest updateInfoRequest = objectMapper.readValue(input.getBody(), UpdateEmailRequest.class);
            boolean isValidOtpCode = codeStorageService.isValidOtpCode(updateInfoRequest.getReplacementEmailAddress(), updateInfoRequest.getOtp(), NotificationType.VERIFY_EMAIL);
            if (!isValidOtpCode) {
                return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1020);
            }
            Optional<ErrorResponse> emailValidationErrors = validationService.validateEmailAddressUpdate(updateInfoRequest.getExistingEmailAddress(), updateInfoRequest.getReplacementEmailAddress());
            if (emailValidationErrors.isPresent()) {
                return generateApiGatewayProxyErrorResponse(400, emailValidationErrors.get());
            }
            if (dynamoService.userExists(updateInfoRequest.getReplacementEmailAddress())) {
                return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1009);
            }
            UserProfile userProfile = dynamoService.getUserProfileByEmail(updateInfoRequest.getExistingEmailAddress());
            Map<String, Object> authorizerParams = input.getRequestContext().getAuthorizer();
            RequestBodyHelper.validatePrincipal(new Subject(userProfile.getPublicSubjectID()), authorizerParams);
            dynamoService.updateEmail(updateInfoRequest.getExistingEmailAddress(), updateInfoRequest.getReplacementEmailAddress());
            LOG.info("Email has successfully been updated. Adding message to SQS queue");
            NotifyRequest notifyRequest = new NotifyRequest(updateInfoRequest.getReplacementEmailAddress(), NotificationType.EMAIL_UPDATED);
            sqsClient.send(objectMapper.writeValueAsString((notifyRequest)));
            auditService.submitAuditEvent(AccountManagementAuditableEvent.UPDATE_EMAIL, context.getAwsRequestId(), sessionId, AuditService.UNKNOWN, userProfile.getSubjectID(), updateInfoRequest.getReplacementEmailAddress(), IpAddressHelper.extractIpAddress(input), userProfile.getPhoneNumber(), PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders()));
            LOG.info("Message successfully added to queue. Generating successful gateway response");
            return generateEmptySuccessApiGatewayResponse();
        } catch (JsonProcessingException | IllegalArgumentException e) {
            return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1001);
        }
    });
}
Also used : UpdateEmailRequest(uk.gov.di.accountmanagement.entity.UpdateEmailRequest) UserProfile(uk.gov.di.authentication.shared.entity.UserProfile) NotifyRequest(uk.gov.di.accountmanagement.entity.NotifyRequest) Subject(com.nimbusds.oauth2.sdk.id.Subject) ErrorResponse(uk.gov.di.authentication.shared.entity.ErrorResponse) ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse(uk.gov.di.authentication.shared.helpers.ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 10 with Subject

use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.

the class AuthoriseAccessTokenHandler method handleRequest.

@Override
public AuthPolicy handleRequest(TokenAuthorizerContext input, Context context) {
    if (input.getType().equals(WARMUP_HEADER)) {
        LOG.info("Warmup Request Received");
        try {
            sleep(configurationService.getWarmupDelayMillis());
        } catch (InterruptedException e) {
            LOG.error("Sleep was interrupted", e);
            throw new RuntimeException("Sleep was interrupted", e);
        }
        LOG.info("Instance warmed for request");
        throw new RuntimeException("Unauthorized");
    } else {
        LOG.info("Request received in AuthoriseAccessTokenHandler");
        try {
            String token = input.getAuthorizationToken();
            AccessToken accessToken = AccessToken.parse(token, AccessTokenType.BEARER);
            SignedJWT signedAccessToken = SignedJWT.parse(accessToken.getValue());
            JWTClaimsSet claimsSet = signedAccessToken.getJWTClaimsSet();
            LocalDateTime localDateTime = LocalDateTime.now();
            Date currentDateTime = Date.from(localDateTime.atZone(ZoneId.of("UTC")).toInstant());
            if (DateUtils.isBefore(claimsSet.getExpirationTime(), currentDateTime, 0)) {
                LOG.warn("Access Token expires at: {}. CurrentDateTime is: {}", claimsSet.getExpirationTime(), currentDateTime);
                throw new RuntimeException("Unauthorized");
            }
            boolean isAccessTokenSignatureValid = tokenValidationService.validateAccessTokenSignature(accessToken);
            if (!isAccessTokenSignatureValid) {
                LOG.warn("Access Token signature is not valid");
                throw new RuntimeException("Unauthorized");
            }
            LOG.info("Successfully validated Access Token signature");
            List<String> scopeList = claimsSet.getStringListClaim("scope");
            if (scopeList == null || !scopeList.contains(CustomScopeValue.ACCOUNT_MANAGEMENT.getValue())) {
                LOG.warn("Access Token scope is not valid or missing");
                throw new RuntimeException("Unauthorized");
            }
            LOG.info("Successfully validated Access Token scope");
            String clientId = claimsSet.getStringClaim("client_id");
            if (clientId == null) {
                LOG.warn("Access Token client_id is missing");
                throw new RuntimeException("Unauthorized");
            }
            if (!clientService.isValidClient(clientId)) {
                LOG.warn("Access Token client_id does not exist in Dynamo. ClientId {}", clientId);
                throw new RuntimeException("Unauthorized");
            }
            String subject = claimsSet.getSubject();
            if (subject == null) {
                LOG.warn("Access Token subject is missing");
                throw new RuntimeException("Unauthorized");
            }
            try {
                dynamoService.getUserProfileFromPublicSubject(subject);
            } catch (Exception e) {
                LOG.error("Unable to retrieve UserProfile from Dynamo with given SubjectID");
                throw new RuntimeException("Unauthorized");
            }
            LOG.info("User found in Dynamo with given SubjectID");
            String methodArn = input.getMethodArn();
            String[] arnPartials = methodArn.split(":");
            String region = arnPartials[3];
            String awsAccountId = arnPartials[4];
            String[] apiGatewayArnPartials = arnPartials[5].split("/");
            String restApiId = apiGatewayArnPartials[0];
            String stage = apiGatewayArnPartials[1];
            LOG.info("Generating AuthPolicy");
            return new AuthPolicy(subject, AuthPolicy.PolicyDocument.getAllowAllPolicy(region, awsAccountId, restApiId, stage));
        } catch (ParseException | java.text.ParseException e) {
            LOG.warn("Unable to parse Access Token");
            throw new RuntimeException("Unauthorized");
        }
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) SignedJWT(com.nimbusds.jwt.SignedJWT) Date(java.util.Date) ParseException(com.nimbusds.oauth2.sdk.ParseException) AuthPolicy(uk.gov.di.accountmanagement.entity.AuthPolicy) AccessToken(com.nimbusds.oauth2.sdk.token.AccessToken) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) ParseException(com.nimbusds.oauth2.sdk.ParseException)

Aggregations

Subject (com.nimbusds.oauth2.sdk.id.Subject)59 Test (org.junit.jupiter.api.Test)36 SignedJWT (com.nimbusds.jwt.SignedJWT)22 Date (java.util.Date)22 ApiGatewayHandlerIntegrationTest (uk.gov.di.authentication.sharedtest.basetest.ApiGatewayHandlerIntegrationTest)19 UserProfile (uk.gov.di.authentication.shared.entity.UserProfile)18 KeyPair (java.security.KeyPair)16 BearerAccessToken (com.nimbusds.oauth2.sdk.token.BearerAccessToken)15 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)13 ParseException (com.nimbusds.oauth2.sdk.ParseException)12 Scope (com.nimbusds.oauth2.sdk.Scope)12 APIGatewayProxyRequestEvent (com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent)11 APIGatewayProxyResponseEvent (com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent)11 AccessToken (com.nimbusds.oauth2.sdk.token.AccessToken)10 ECKeyGenerator (com.nimbusds.jose.jwk.gen.ECKeyGenerator)9 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)9 ECDSASigner (com.nimbusds.jose.crypto.ECDSASigner)8 Issuer (com.nimbusds.oauth2.sdk.id.Issuer)8 IDTokenClaimsSet (com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet)8 LocalDateTime (java.time.LocalDateTime)8