Search in sources :

Example 1 with AccessTokenResponse

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;
    }
}
Also used : ResponseEntity(org.springframework.http.ResponseEntity) AccessTokenReWriteException(com.forgerock.openbanking.common.error.exception.AccessTokenReWriteException) ParseException(java.text.ParseException) AccessTokenResponse(com.forgerock.openbanking.model.oidc.AccessTokenResponse)

Example 2 with AccessTokenResponse

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");
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ResponseEntity(org.springframework.http.ResponseEntity) AccessTokenReWriteException(com.forgerock.openbanking.common.error.exception.AccessTokenReWriteException) AccessTokenResponse(com.forgerock.openbanking.model.oidc.AccessTokenResponse) Test(org.junit.Test)

Example 3 with AccessTokenResponse

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);
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ResponseEntity(org.springframework.http.ResponseEntity) AccessTokenResponse(com.forgerock.openbanking.model.oidc.AccessTokenResponse) Test(org.junit.Test)

Example 4 with AccessTokenResponse

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()));
    }
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ResponseEntity(org.springframework.http.ResponseEntity) HttpStatus(org.springframework.http.HttpStatus) OBErrorResponseException(com.forgerock.openbanking.exceptions.OBErrorResponseException) AccessTokenResponse(com.forgerock.openbanking.model.oidc.AccessTokenResponse)

Example 5 with AccessTokenResponse

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);
}
Also used : ResponseEntity(org.springframework.http.ResponseEntity) AccessTokenResponse(com.forgerock.openbanking.model.oidc.AccessTokenResponse) PairClientIDAuthMethod(com.forgerock.openbanking.aspsp.as.service.PairClientIDAuthMethod) Test(org.junit.Test)

Aggregations

AccessTokenResponse (com.forgerock.openbanking.model.oidc.AccessTokenResponse)10 ResponseEntity (org.springframework.http.ResponseEntity)9 Test (org.junit.Test)7 HttpHeaders (org.springframework.http.HttpHeaders)7 PairClientIDAuthMethod (com.forgerock.openbanking.aspsp.as.service.PairClientIDAuthMethod)5 OBErrorResponseException (com.forgerock.openbanking.exceptions.OBErrorResponseException)4 AccessTokenReWriteException (com.forgerock.openbanking.common.error.exception.AccessTokenReWriteException)3 AMGateway (com.forgerock.openbanking.am.gateway.AMGateway)1 GrantType (com.forgerock.openbanking.constants.OIDCConstants.GrantType)1 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)1 URI (java.net.URI)1 ParseException (java.text.ParseException)1 HttpStatus (org.springframework.http.HttpStatus)1 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)1