use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class LoginHandlerTest method shouldReturn401IfMigratedUserHasInvalidCredentials.
@Test
void shouldReturn401IfMigratedUserHasInvalidCredentials() {
String legacySubjectId = new Subject().getValue();
UserProfile userProfile = generateUserProfile(legacySubjectId);
when(authenticationService.getUserProfileByEmailMaybe(EMAIL)).thenReturn(Optional.of(userProfile));
when(userMigrationService.processMigratedUser(userCredentials, PASSWORD)).thenReturn(false);
APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
event.setHeaders(Map.of("Session-Id", session.getSessionId()));
event.setBody(format("{ \"password\": \"%s\", \"email\": \"%s\" }", PASSWORD, EMAIL));
usingValidSession();
APIGatewayProxyResponseEvent result = handler.handleRequest(event, context);
assertThat(result, hasStatus(401));
assertThat(result, hasJsonBody(ErrorResponse.ERROR_1008));
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class AuthoriseAccessTokenHandler method authoriseAccessTokenHandler.
public AuthPolicy authoriseAccessTokenHandler(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();
Date currentDateTime = NowHelper.now();
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");
}
}
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class RemoveAccountHandler method removeAccountRequestHandler.
public APIGatewayProxyResponseEvent removeAccountRequestHandler(APIGatewayProxyRequestEvent input, Context context) {
return isWarming(input).orElseGet(() -> {
try {
String sessionId = RequestHeaderHelper.getHeaderValueOrElse(input.getHeaders(), SESSION_ID_HEADER, "");
attachSessionIdToLogs(sessionId);
LOG.info("RemoveAccountHandler received request");
RemoveAccountRequest removeAccountRequest = objectMapper.readValue(input.getBody(), RemoveAccountRequest.class);
String email = removeAccountRequest.getEmail();
UserProfile userProfile = authenticationService.getUserProfileByEmailMaybe(email).orElseThrow(() -> new RuntimeException("User not found"));
Map<String, Object> authorizerParams = input.getRequestContext().getAuthorizer();
RequestBodyHelper.validatePrincipal(new Subject(userProfile.getPublicSubjectID()), authorizerParams);
authenticationService.removeAccount(email);
LOG.info("User account removed. Adding message to SQS queue");
NotifyRequest notifyRequest = new NotifyRequest(email, NotificationType.DELETE_ACCOUNT);
sqsClient.send(objectMapper.writeValueAsString((notifyRequest)));
LOG.info("Remove account message successfully added to queue. Generating successful gateway response");
auditService.submitAuditEvent(AccountManagementAuditableEvent.DELETE_ACCOUNT, context.getAwsRequestId(), sessionId, AuditService.UNKNOWN, userProfile.getSubjectID(), userProfile.getEmail(), IpAddressHelper.extractIpAddress(input), userProfile.getPhoneNumber(), PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders()));
return generateEmptySuccessApiGatewayResponse();
} catch (JsonException e) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1001);
}
});
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class UpdatePhoneNumberHandler method updatePhoneNumberRequestHandler.
public APIGatewayProxyResponseEvent updatePhoneNumberRequestHandler(APIGatewayProxyRequestEvent input, Context context) {
return isWarming(input).orElseGet(() -> {
String sessionId = RequestHeaderHelper.getHeaderValueOrElse(input.getHeaders(), SESSION_ID_HEADER, "");
attachSessionIdToLogs(sessionId);
LOG.info("UpdatePhoneNumberHandler received request");
try {
UpdatePhoneNumberRequest updatePhoneNumberRequest = objectMapper.readValue(input.getBody(), UpdatePhoneNumberRequest.class);
boolean isValidOtpCode = codeStorageService.isValidOtpCode(updatePhoneNumberRequest.getEmail(), updatePhoneNumberRequest.getOtp(), NotificationType.VERIFY_PHONE_NUMBER);
if (!isValidOtpCode) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1020);
}
UserProfile userProfile = dynamoService.getUserProfileByEmail(updatePhoneNumberRequest.getEmail());
Map<String, Object> authorizerParams = input.getRequestContext().getAuthorizer();
RequestBodyHelper.validatePrincipal(new Subject(userProfile.getPublicSubjectID()), authorizerParams);
dynamoService.updatePhoneNumber(updatePhoneNumberRequest.getEmail(), updatePhoneNumberRequest.getPhoneNumber());
LOG.info("Phone Number has successfully been updated. Adding message to SQS queue");
NotifyRequest notifyRequest = new NotifyRequest(updatePhoneNumberRequest.getEmail(), NotificationType.PHONE_NUMBER_UPDATED);
sqsClient.send(objectMapper.writeValueAsString((notifyRequest)));
auditService.submitAuditEvent(AccountManagementAuditableEvent.UPDATE_PHONE_NUMBER, context.getAwsRequestId(), sessionId, AuditService.UNKNOWN, userProfile.getSubjectID(), userProfile.getEmail(), IpAddressHelper.extractIpAddress(input), updatePhoneNumberRequest.getPhoneNumber(), PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders()));
LOG.info("Message successfully added to queue. Generating successful gateway response");
return generateEmptySuccessApiGatewayResponse();
} catch (JsonException | IllegalArgumentException e) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1001);
}
});
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class AuthoriseAccessTokenIntegrationTest method shouldThrowExceptionWhenAccessTokenHasUnknownSubject.
@Test
void shouldThrowExceptionWhenAccessTokenHasUnknownSubject() {
var publicSubject = new Subject().getValue();
var scopes = asList(OIDCScopeValue.OPENID.getValue(), CustomScopeValue.ACCOUNT_MANAGEMENT.getValue());
var accessToken = generateSignedAccessToken(scopes, CLIENT_ID.getValue(), publicSubject, validDate);
setUpClient(scopes);
setUpClient(scopes);
expectException(() -> makeRequest(accessToken.toAuthorizationHeader()));
}
Aggregations