use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class LogoutHandlerTest method shouldRedirectToDefaultLogoutUriWithErrorMessageWhenSignaturenIdTokenIsInvalid.
@Test
public void shouldRedirectToDefaultLogoutUriWithErrorMessageWhenSignaturenIdTokenIsInvalid() throws URISyntaxException, JOSEException {
ECKey ecSigningKey = new ECKeyGenerator(Curve.P_256).algorithm(JWSAlgorithm.ES256).generate();
SignedJWT signedJWT = TokenGeneratorHelper.generateIDToken("invalid-client-id", new Subject(), "http://localhost-rp", ecSigningKey);
when(tokenValidationService.isTokenSignatureValid(signedJWT.serialize())).thenReturn(false);
APIGatewayProxyRequestEvent event = generateRequestEvent(Map.of("id_token_hint", signedJWT.serialize(), "post_logout_redirect_uri", CLIENT_LOGOUT_URI.toString()));
session.getClientSessions().add(CLIENT_SESSION_ID);
generateSessionFromCookie(session);
setupClientSessionToken(signedJWT);
APIGatewayProxyResponseEvent response = handler.handleRequest(event, context);
assertThat(response, hasStatus(302));
ErrorObject errorObject = new ErrorObject(OAuth2Error.INVALID_REQUEST_CODE, "unable to validate id_token_hint");
URIBuilder uriBuilder = new URIBuilder(DEFAULT_LOGOUT_URI);
uriBuilder.addParameter("error_code", errorObject.getCode());
uriBuilder.addParameter("error_description", errorObject.getDescription());
URI expectedUri = uriBuilder.build();
assertThat(response.getHeaders().get(ResponseHeaders.LOCATION), equalTo(expectedUri.toString()));
verify(auditService).submitAuditEvent(OidcAuditableEvent.LOG_OUT_SUCCESS, "aws-session-id", SESSION_ID, AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN, "123.123.123.123", AuditService.UNKNOWN, PERSISTENT_SESSION_ID);
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class LogoutHandlerTest method shouldRedirectToDefaultLogoutUriWithErrorMessageWhenClientIsNotFoundInClientRegistry.
@Test
public void shouldRedirectToDefaultLogoutUriWithErrorMessageWhenClientIsNotFoundInClientRegistry() throws JOSEException, URISyntaxException {
ECKey ecSigningKey = new ECKeyGenerator(Curve.P_256).algorithm(JWSAlgorithm.ES256).generate();
SignedJWT signedJWT = TokenGeneratorHelper.generateIDToken("invalid-client-id", SUBJECT, "http://localhost-rp", ecSigningKey);
when(tokenValidationService.isTokenSignatureValid(signedJWT.serialize())).thenReturn(true);
APIGatewayProxyRequestEvent event = generateRequestEvent(Map.of("id_token_hint", signedJWT.serialize(), "post_logout_redirect_uri", CLIENT_LOGOUT_URI.toString(), "state", STATE.toString()));
session.getClientSessions().add(CLIENT_SESSION_ID);
generateSessionFromCookie(session);
setupClientSessionToken(signedJWT);
APIGatewayProxyResponseEvent response = handler.handleRequest(event, context);
assertThat(response, hasStatus(302));
ErrorObject errorObject = new ErrorObject(OAuth2Error.UNAUTHORIZED_CLIENT_CODE, "client not found");
URIBuilder uriBuilder = new URIBuilder(DEFAULT_LOGOUT_URI);
uriBuilder.addParameter("state", STATE.getValue());
uriBuilder.addParameter("error_code", errorObject.getCode());
uriBuilder.addParameter("error_description", errorObject.getDescription());
URI expectedUri = uriBuilder.build();
assertThat(response.getHeaders().get(ResponseHeaders.LOCATION), equalTo(expectedUri.toString()));
verify(auditService).submitAuditEvent(OidcAuditableEvent.LOG_OUT_SUCCESS, "aws-session-id", SESSION_ID, "invalid-client-id", AuditService.UNKNOWN, AuditService.UNKNOWN, "123.123.123.123", AuditService.UNKNOWN, PERSISTENT_SESSION_ID);
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class UserInfoHandlerTest method shouldReturn200WithUserInfoBasedOnScopesForSuccessfulRequest.
@Test
void shouldReturn200WithUserInfoBasedOnScopesForSuccessfulRequest() throws ParseException, AccessTokenException {
AccessToken accessToken = new BearerAccessToken();
UserInfo userInfo = new UserInfo(SUBJECT);
userInfo.setEmailVerified(true);
userInfo.setPhoneNumberVerified(true);
userInfo.setPhoneNumber(PHONE_NUMBER);
userInfo.setEmailAddress(EMAIL_ADDRESS);
when(accessTokenService.parse(accessToken.toAuthorizationHeader(), false)).thenReturn(accessTokenInfo);
when(userInfoService.populateUserInfo(accessTokenInfo, false)).thenReturn(userInfo);
APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
event.setHeaders(Map.of("Authorization", accessToken.toAuthorizationHeader()));
APIGatewayProxyResponseEvent result = handler.handleRequest(event, context);
assertThat(result, hasStatus(200));
UserInfo parsedResultBody = UserInfo.parse(result.getBody());
assertThat(parsedResultBody.getSubject(), equalTo(SUBJECT));
assertThat(parsedResultBody.getEmailAddress(), equalTo(EMAIL_ADDRESS));
assertTrue(parsedResultBody.getEmailVerified());
assertThat(parsedResultBody.getPhoneNumber(), equalTo(PHONE_NUMBER));
assertTrue(parsedResultBody.getPhoneNumberVerified());
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class AccessTokenServiceTest method createSignedAccessToken.
private AccessToken createSignedAccessToken(OIDCClaimsRequest identityClaims, boolean expired) {
try {
var expiryDate = expired ? NowHelper.nowMinus(2, ChronoUnit.MINUTES) : NowHelper.nowPlus(3, ChronoUnit.MINUTES);
var ecSigningKey = new ECKeyGenerator(Curve.P_256).keyID(KEY_ID).algorithm(JWSAlgorithm.ES256).generate();
var signedJWT = TokenGeneratorHelper.generateSignedToken(CLIENT_ID, BASE_URL, SCOPES, new ECDSASigner(ecSigningKey), SUBJECT, ecSigningKey.getKeyID(), expiryDate, identityClaims);
return new BearerAccessToken(signedJWT.serialize());
} catch (JOSEException e) {
throw new RuntimeException(e);
}
}
use of com.nimbusds.oauth2.sdk.id.Subject in project di-authentication-api by alphagov.
the class AccessTokenService method parse.
public AccessTokenInfo parse(String authorizationHeader, boolean identityEnabled) throws AccessTokenException {
AccessToken accessToken;
try {
accessToken = AccessToken.parse(authorizationHeader, AccessTokenType.BEARER);
} catch (com.nimbusds.oauth2.sdk.ParseException e) {
LOG.warn("Unable to parse AccessToken");
throw new AccessTokenException("Unable to parse AccessToken", BearerTokenError.INVALID_TOKEN);
}
SignedJWT signedJWT;
try {
signedJWT = SignedJWT.parse(accessToken.getValue());
var currentDateTime = NowHelper.now();
if (DateUtils.isBefore(signedJWT.getJWTClaimsSet().getExpirationTime(), currentDateTime, 0)) {
LOG.warn("Access Token has expired. Access Token expires at: {}. CurrentDateTime is: {}", signedJWT.getJWTClaimsSet().getExpirationTime(), currentDateTime);
throw new AccessTokenException(INVALID_ACCESS_TOKEN, BearerTokenError.INVALID_TOKEN);
}
if (!tokenValidationService.validateAccessTokenSignature(accessToken)) {
LOG.warn("Unable to validate AccessToken signature");
throw new AccessTokenException("Unable to validate AccessToken signature", BearerTokenError.INVALID_TOKEN);
}
var clientID = signedJWT.getJWTClaimsSet().getStringClaim("client_id");
var client = clientService.getClient(clientID);
attachLogFieldToLogs(CLIENT_ID, clientID);
if (client.isEmpty()) {
LOG.warn("Client not found");
throw new AccessTokenException("Client not found", BearerTokenError.INVALID_TOKEN);
}
var scopes = JSONArrayUtils.parse(signedJWT.getJWTClaimsSet().getClaim("scope").toString()).stream().map(Objects::toString).collect(Collectors.toList());
if (!areScopesValid(scopes) || !client.get().getScopes().containsAll(scopes)) {
LOG.warn("Invalid Scopes: {}", scopes);
throw new AccessTokenException("Invalid Scopes", OAuth2Error.INVALID_SCOPE);
}
List<String> identityClaims = null;
if (identityEnabled) {
identityClaims = getIdentityClaims(signedJWT.getJWTClaimsSet());
}
var subject = signedJWT.getJWTClaimsSet().getSubject();
var accessTokenStore = getAccessTokenStore(clientID, subject);
if (accessTokenStore.isEmpty()) {
LOG.warn("Access Token Store is empty. Access Token expires at: {}. CurrentDateTime is: {}. JWTID in Access Token sent in request: {}", signedJWT.getJWTClaimsSet().getExpirationTime(), currentDateTime, signedJWT.getJWTClaimsSet().getJWTID());
throw new AccessTokenException(INVALID_ACCESS_TOKEN, BearerTokenError.INVALID_TOKEN);
}
if (!accessTokenStore.get().getToken().equals(accessToken.getValue())) {
LOG.warn("Access Token in Access Token Store is different to Access Token sent in request");
var storeJwtId = SignedJWT.parse(accessTokenStore.get().getToken()).getJWTClaimsSet().getJWTID();
LOG.warn("JWTID in AccessTokenStore: {} compared to JWTID in Access Token sent in request: {}", storeJwtId, signedJWT.getJWTClaimsSet().getJWTID());
throw new AccessTokenException(INVALID_ACCESS_TOKEN, BearerTokenError.INVALID_TOKEN);
}
return new AccessTokenInfo(accessTokenStore.get(), subject, scopes, identityClaims);
} catch (ParseException e) {
LOG.warn("Unable to parse AccessToken to SignedJWT");
throw new AccessTokenException("Unable to parse AccessToken to SignedJWT", BearerTokenError.INVALID_TOKEN);
} catch (com.nimbusds.oauth2.sdk.ParseException e) {
LOG.warn("Unable to parse ClaimSet in AccessToken");
throw new AccessTokenException("Unable to parse ClaimSet in AccessToken", BearerTokenError.INVALID_TOKEN);
}
}
Aggregations