use of com.forgerock.openbanking.model.oidc.AccessTokenResponse in project openbanking-aspsp by OpenBankingToolkit.
the class JwtOverridingService method rewriteAccessTokenResponseIdToken.
/**
* rewriteAccessTokenResponseIdToken - creates a new id_token, signed with the correct ID and containing the
* correct kid in the header. This is required as currently AM uses a different algorithm to create the kid than
* the OB Directory does, so when signing with the OB Signing Key or an OBSeal then the key ID in the AM
* generated id_token doesn't match the kid in the OB Directory jwks_uri and hence the id_token can't be
* validated. To fix that we resign it using the crypto API which produces a verifyable token.
*
* @param responseEntity the response entity that contains the id_token. Note, the id_token will only exist if
* the request to get the access token contained the openid scope, which is not mandatory.
* If the response entity does not contain an id_token then there is nothing to be
* re-written and the responseEntity will be returned.
* @return Either the responseEntity passed to the method (if it contained no id_token to be re-written), or a
* new responseEntity containing a new id_token that is verifiable.
* @throws AccessTokenReWriteException
*/
public ResponseEntity rewriteAccessTokenResponseIdToken(ResponseEntity responseEntity) throws AccessTokenReWriteException {
if (responseEntity == null) {
throw new AccessTokenReWriteException("rewriteAccessTokenResponseIdToken() responseEntity is null");
}
if (responseEntity.getStatusCode() != HttpStatus.OK) {
log.debug("rewriteAccessTokenResponseIdToken() responseEntity does not have success status");
throw new AccessTokenReWriteException("Failed to rewrite access token response's id_token: responseEntity" + " status code was " + responseEntity.getStatusCode() + ". Expected 200 (OK)");
}
AccessTokenResponse accessTokenResponse = (AccessTokenResponse) responseEntity.getBody();
if (accessTokenResponse == null) {
log.debug("rewriteAccessTokenResponseIdToken() Expected body in responseEntity '{}'", responseEntity);
throw new AccessTokenReWriteException("Failed to rewrite access token response's id_token; responseEntity" + " has no body");
}
String id_token = accessTokenResponse.getId_token();
if (id_token == null) {
log.debug("rewriteAccessTokenResponseIdToken() responseEntity body contains no id_token; '{}'", accessTokenResponse);
return responseEntity;
} else {
try {
String rewrittenJWS = rewriteJWS(id_token);
if (rewrittenJWS == null || rewrittenJWS.isEmpty() || rewrittenJWS.isBlank()) {
log.debug("rewriteAccessTokenResponseIdToken() rewrittenJWS is null or empty.");
throw new AccessTokenReWriteException("Failed to rewrite access token response's id_token; " + "re-written JWS is null or empty");
}
accessTokenResponse.setId_token(rewrittenJWS);
} catch (ParseException e) {
log.debug("rewriteAccessTokenResponseIdToken() Failed to parse id_token: '{}'", id_token, e);
throw new AccessTokenReWriteException("Failed to rewrite access token response's id_token; Could not " + "parse id_token", e);
}
ResponseEntity rewrittenResponseEntity = ResponseEntity.status(HttpStatus.OK).body(accessTokenResponse);
log.trace("rewriteAccessTokenResponseIdToken() re-written responseEntity is '{}'", responseEntity);
return rewrittenResponseEntity;
}
}
use of com.forgerock.openbanking.model.oidc.AccessTokenResponse in project openbanking-aspsp by OpenBankingToolkit.
the class JwtOverridingServiceTest method shouldFailWhenBodyHasInvalidIdToken_rewriteAccessTokenResponseIdToken.
@Test
public void shouldFailWhenBodyHasInvalidIdToken_rewriteAccessTokenResponseIdToken() {
// Given
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Location", "https://location");
AccessTokenResponse accessTokenResponse = new AccessTokenResponse();
accessTokenResponse.setId_token("InvalidToken");
ResponseEntity responseEntity = new ResponseEntity(accessTokenResponse, httpHeaders, HttpStatus.OK);
// Then
AccessTokenReWriteException accessTokenReWriteException = catchThrowableOfType(() -> this.jwtOverridingService.rewriteAccessTokenResponseIdToken(responseEntity), AccessTokenReWriteException.class);
// When
assertThat(accessTokenReWriteException.getMessage()).contains("Could not parse id_token");
}
use of com.forgerock.openbanking.model.oidc.AccessTokenResponse in project openbanking-aspsp by OpenBankingToolkit.
the class JwtOverridingServiceTest method shouldReturnOrignialWhenBodyHasNoIdToken_rewriteAccessTokenResponseIdToken.
@Test
public void shouldReturnOrignialWhenBodyHasNoIdToken_rewriteAccessTokenResponseIdToken() throws AccessTokenReWriteException {
// Given
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Location", "https://location");
AccessTokenResponse accessTokenResponse = new AccessTokenResponse();
ResponseEntity responseEntity = new ResponseEntity(accessTokenResponse, httpHeaders, HttpStatus.OK);
// Then
ResponseEntity result = jwtOverridingService.rewriteAccessTokenResponseIdToken(responseEntity);
// When
assertThat(result).isSameAs(responseEntity);
}
use of com.forgerock.openbanking.model.oidc.AccessTokenResponse in project openbanking-aspsp by OpenBankingToolkit.
the class HeadLessAccessTokenService method exchangeAuthorizationCodeForAccessToken.
private ResponseEntity<AccessTokenResponse> exchangeAuthorizationCodeForAccessToken(AMGateway amGateway, PairClientIDAuthMethod tokenEndpointAuthMethods, MultiValueMap paramMap, HttpServletRequest request, String code) throws OBErrorResponseException {
StringBuilder requestBody = new StringBuilder();
requestBody.append("grant_type=authorization_code");
Map<String, String> parameters = paramMap.toSingleValueMap();
switch(tokenEndpointAuthMethods.authMethod) {
case CLIENT_SECRET_BASIC:
// Would be in the request header already
break;
case TLS_CLIENT_AUTH:
requestBody.append("&client_id=").append(encode(parameters.get("client_id")));
break;
case CLIENT_SECRET_POST:
requestBody.append("&client_id=").append(encode(parameters.get("client_id")));
requestBody.append("&client_secret=").append(encode(parameters.get("client_secret")));
break;
case CLIENT_SECRET_JWT:
throw new RuntimeException("Not Implemented");
case PRIVATE_KEY_JWT:
requestBody.append("&client_assertion_type=").append(encode(parameters.get("client_assertion_type")));
requestBody.append("&client_assertion=").append(encode(parameters.get("client_assertion")));
break;
}
requestBody.append("&redirect_uri=").append(encode(parameters.get("redirect_uri")));
requestBody.append("&code=").append(encode(code));
HttpHeaders httpHeaders = new HttpHeaders();
// httpHeaders.add("Content-Type", "application/x-www-form-urlencoded");
ResponseEntity responseFromAM = amGateway.toAM(request, httpHeaders, new ParameterizedTypeReference<AccessTokenResponse>() {
}, requestBody.toString());
HttpStatus statusCode = responseFromAM.getStatusCode();
if (!statusCode.is2xxSuccessful() && !statusCode.is3xxRedirection()) {
log.warn("getAccessToken() unsuccessful call to headlessAuthTokenService. StatusCode: {}, body: {}", statusCode, responseFromAM.getBody());
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_INVALID.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_INVALID.toOBError1(responseFromAM.getBody()));
}
Object responseBody = responseFromAM.getBody();
if (responseBody instanceof AccessTokenResponse) {
ResponseEntity<AccessTokenResponse> responseEntity = new ResponseEntity<>((AccessTokenResponse) responseFromAM.getBody(), responseFromAM.getStatusCode());
return responseEntity;
} else {
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_INVALID.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_INVALID.toOBError1(responseFromAM.getBody()));
}
}
use of com.forgerock.openbanking.model.oidc.AccessTokenResponse in project openbanking-aspsp by OpenBankingToolkit.
the class AccessTokenApiControllerTest method successWithHeadlessAuth_getAccessToken.
@Test
public void successWithHeadlessAuth_getAccessToken() throws OBErrorResponseException, OBErrorException, AccessTokenReWriteException {
// Given
MultiValueMap<String, String> params = getParamsMap(GrantType.HEADLESS_AUTH);
PairClientIDAuthMethod pairClientIDAuthMethod = getClientIDAuthMethod(CLIENT_SECRET_BASIC);
given(matlsRequestVerificationService.verifyMATLSMatchesRequest(params, authorization, principal)).willReturn(pairClientIDAuthMethod);
ResponseEntity<AccessTokenResponse> responseEntity = new ResponseEntity<>(null, httpHeaders, HttpStatus.FOUND);
given(headLessAccessTokenService.getAccessToken(amGateway, pairClientIDAuthMethod, params, request)).willReturn(responseEntity);
ResponseEntity<Object> modifiedResponseEntity = new ResponseEntity<>(null, httpHeaders, HttpStatus.OK);
given(jwtOverridingService.rewriteAccessTokenResponseIdToken(responseEntity)).willReturn(modifiedResponseEntity);
// When
ResponseEntity result = this.accessTokenApiController.getAccessToken(params, authorization, principal, request);
// Then
assertThat(result).isNotNull();
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
}
Aggregations