Search in sources :

Example 26 with OBErrorException

use of com.forgerock.openbanking.exceptions.OBErrorException in project openbanking-aspsp by OpenBankingToolkit.

the class DataApiController method deleteUserData.

@Override
public ResponseEntity deleteUserData(@ApiParam(value = "PSU User session") @CookieValue(value = "obri-session", required = true) String obriSession, @ApiParam(value = "The access token") @RequestHeader(name = HttpHeaders.AUTHORIZATION, required = true) String authorization, Principal principal) throws OBErrorException, OAuth2InvalidClientException, OAuth2BearerTokenUsageInvalidTokenException {
    try {
        log.debug("deleteUserData() called");
        String tppName = psd2WithSessionApiHelperService.getTppName(principal);
        String psuName = psd2WithSessionApiHelperService.getPsuNameFromSession(obriSession);
        verifyAccessTokenAndVerifyTppIdentity(authorization, tppName);
        log.info("deleteUserData() called with session for psu '{}' by tpp '{}'", psuName, tppName);
        userDataService.deleteUserData(psuName);
        return ResponseEntity.ok(userDataService.exportUserData(psuName));
    } catch (HttpClientErrorException e) {
        if (e.getStatusCode() == HttpStatus.BAD_REQUEST) {
            log.debug("TPP bad request: {}", e.getResponseBodyAsString(), e);
            throw new OBErrorException(OBRIErrorType.DATA_INVALID_REQUEST, e.getResponseBodyAsString());
        } else {
            log.error("Internal server: {}", e.getResponseBodyAsString(), e);
            throw new OBErrorException(OBRIErrorType.SERVER_ERROR);
        }
    }
}
Also used : HttpClientErrorException(org.springframework.web.client.HttpClientErrorException) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException)

Example 27 with OBErrorException

use of com.forgerock.openbanking.exceptions.OBErrorException in project openbanking-aspsp by OpenBankingToolkit.

the class AuthorisationApiController method getAuthorisation.

/**
 * getAuthorisation - Implementation of the /authorize OIDC Connect endpoint.
 * @param responseType required = true
 * @param clientId required = true
 * @param state required = false
 * @param nonce required = false
 * @param scopes required = false
 * @param redirectUri required = false,
 * @param requestParametersSerialised required = true)
 * @param isHeadlessEnabled required = false, defaultValue = "false"
 * @param username required = false, defaultValue = ""
 * @param password required = false, defaultValue = ""
 * @param ssoToken (required = false)
 * @param body required = false
 * @return A <code>ResponseEntity</code> containing the result of authorization request
 * @throws OBErrorResponseException or OBErrorException when errors occur that prevent authorization
 */
@Override
public ResponseEntity getAuthorisation(String responseType, String clientId, String state, String nonce, String scopes, String redirectUri, String requestParametersSerialised, boolean isHeadlessEnabled, String username, String password, String ssoToken, MultiValueMap body, HttpServletRequest request) throws OBErrorResponseException, OBErrorException {
    // Initialisation the response entity, it will be overwritten with am response.
    ResponseEntity responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    try {
        // FAPI compliant ('code id_token'): https://github.com/ForgeCloud/ob-deploy/issues/674
        if (!discoveryConfig.getSupportedResponseTypes().contains(responseType)) {
            log.error("The response types requested '" + responseType + "' don't match with the response types " + "supported '" + discoveryConfig.getSupportedResponseTypes() + "' by as-api");
            throw new OBErrorResponseException(OBRIErrorType.REQUEST_RESPONSE_TYPE_MISMATCH.getHttpStatus(), OBRIErrorResponseCategory.REQUEST_INVALID, OBRIErrorType.REQUEST_RESPONSE_TYPE_MISMATCH.toOBError1(responseType, discoveryConfig.getSupportedResponseTypes().toString()));
        }
        SignedJWT requestParameterJwt = validateRequestParameter(responseType, clientId, state, nonce, scopes, redirectUri, requestParametersSerialised);
        requestParametersSerialised = requestParameterJwt.serialize();
        try {
            state = getState(state, requestParameterJwt);
        } catch (ParseException e) {
            throw new OBErrorResponseException(OBRIErrorType.REQUEST_PARAMETER_JWT_INVALID.getHttpStatus(), OBRIErrorResponseCategory.REQUEST_INVALID, OBRIErrorType.REQUEST_PARAMETER_JWT_INVALID.toOBError1(e.getMessage()));
        }
        AMGateway amGateway = amGatewayService.getAmGateway(requestParametersSerialised);
        if (isHeadlessAlwaysEnabled || isHeadlessEnabled) {
            log.debug("getAuthorisation() performing headless authorisation");
            responseEntity = headLessAuthorisationService.getAuthorisation(amGateway, responseType, clientId, state, nonce, scopes, redirectUri, requestParametersSerialised, username, password);
        } else {
            log.debug("getAuthorisation() delegating authorisation to AM");
            HashMap<String, String> queryParameters = new HashMap<>();
            queryParameters.put("request", requestParametersSerialised);
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Cookie", cookieName + "=" + ssoToken);
            responseEntity = amGateway.toAM(request, httpHeaders, queryParameters, new ParameterizedTypeReference<String>() {
            }, body);
        }
        log.debug("getAuthorisation() responseEntity {}", responseEntity);
        // re-write it to appear as a fragment
        if (hasQueryParamIdToken(responseEntity)) {
            responseEntity = convertQueryToFragment(responseEntity.getHeaders().getLocation(), responseEntity.getHeaders(), state);
            return responseEntity;
        }
        // Rewriting the response as we need to re-sign the id token. We can assume the id_token will exist as a fragment
        if (hasFragmentIdToken(responseEntity)) {
            try {
                responseEntity = this.jwtOverridingService.rewriteIdTokenFragmentInLocationHeader(responseEntity);
                tokenUsageService.incrementTokenUsage(TokenUsage.ID_TOKEN);
            } catch (AccessTokenReWriteException e) {
                String supportUID = UUID.randomUUID().toString();
                log.info("getAuthorisation() Failed to re-write the id_token", e);
                throw new OBErrorResponseException(OBRIErrorType.AUTHORIZE_INVALID_ID_TOKEN.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.AUTHORIZE_INVALID_ID_TOKEN.toOBError1(supportUID));
            }
        } else {
            log.debug("responseEntity {} is null or is not a redirection", responseEntity);
        }
    } catch (OBErrorResponseException | OBErrorException obException) {
        log.error("Authorisation error '{}', building the redirect action", obException.getMessage());
        if (redirectUri != null && state != null) {
            RedirectionAction redirectionAction = buildRedirectionAction(obException, redirectUri, state);
            return ResponseEntity.status(HttpStatus.FOUND).header("Location", redirectionAction.getRedirectUri()).build();
        }
    }
    return responseEntity;
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) RedirectionAction(com.forgerock.openbanking.common.model.rcs.RedirectionAction) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) SignedJWT(com.nimbusds.jwt.SignedJWT) ResponseEntity(org.springframework.http.ResponseEntity) AMGateway(com.forgerock.openbanking.am.gateway.AMGateway) ParameterizedTypeReference(org.springframework.core.ParameterizedTypeReference) OBErrorResponseException(com.forgerock.openbanking.exceptions.OBErrorResponseException) AccessTokenReWriteException(com.forgerock.openbanking.common.error.exception.AccessTokenReWriteException) ParseException(java.text.ParseException)

Example 28 with OBErrorException

use of com.forgerock.openbanking.exceptions.OBErrorException in project openbanking-aspsp by OpenBankingToolkit.

the class AuthorisationApiController method buildRedirectionAction.

private RedirectionAction buildRedirectionAction(Exception obException, String redirectUri, String state) {
    UriComponents uriComponents = UriComponentsBuilder.newInstance().build();
    if (obException instanceof OBErrorException) {
        OBErrorException obErrorException = (OBErrorException) obException;
        uriComponents = UriComponentsBuilder.fromHttpUrl(redirectUri).fragment("error=invalid_request_object&state=" + state + "&error_description=" + String.format(obErrorException.getObriErrorType().getMessage(), obErrorException.getArgs())).encode().build();
    } else if (obException instanceof OBErrorResponseException) {
        OBErrorResponseException obErrorResponseException = (OBErrorResponseException) obException;
        uriComponents = UriComponentsBuilder.fromHttpUrl(redirectUri).fragment("error=invalid_request_object&state=" + state + "&error_description=" + obErrorResponseException.getErrors().get(0).getMessage()).encode().build();
    }
    return RedirectionAction.builder().redirectUri(uriComponents.toUriString()).requestMethod(HttpMethod.GET).build();
}
Also used : UriComponents(org.springframework.web.util.UriComponents) OBErrorResponseException(com.forgerock.openbanking.exceptions.OBErrorResponseException) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException)

Example 29 with OBErrorException

use of com.forgerock.openbanking.exceptions.OBErrorException in project openbanking-aspsp by OpenBankingToolkit.

the class RCSDetailsGatewayApiController method details.

@Override
public ResponseEntity details(@RequestBody String consentRequestJwt, @CookieValue(value = "${am.cookie.name}") String ssoToken) throws OBErrorException {
    LOGGER.debug("Received a consent request with consent_request='{}'", consentRequestJwt);
    try {
        // Verify the RCS JWT
        LOGGER.debug("Validate consent request JWS");
        // TODO disabling this for now as the consent request JWT as a very short period of life
        // cryptoApiClient.validateJws(consentRequestJwt, amOpenBankingConfiguration.getIssuerID(), amOpenBankingConfiguration.jwksUri);
        LOGGER.debug("Parse consent request JWS");
        SignedJWT signedJWT = (SignedJWT) JWTParser.parse(consentRequestJwt);
        LOGGER.debug("Read payment ID from the claims");
        // Read the claims
        Claims claims = JwsClaimsUtils.getClaims(signedJWT);
        if (!claims.getIdTokenClaims().containsKey(OpenBankingConstants.IdTokenClaim.INTENT_ID)) {
            throw new OBErrorException(OBRIErrorType.RCS_CONSENT_REQUEST_INVALID, "No intent ID");
        }
        String intentId = claims.getIdTokenClaims().get(OpenBankingConstants.IdTokenClaim.INTENT_ID).getValue();
        String clientId = signedJWT.getJWTClaimsSet().getStringClaim(RCSConstants.Claims.CLIENT_ID);
        Map<String, String> profile = userProfileService.getProfile(ssoToken, amOpenBankingConfiguration.endpointUserProfile, amOpenBankingConfiguration.cookieName);
        String username = profile.get(amOpenBankingConfiguration.userProfileId);
        List<AccountWithBalance> accounts = getAccountOrGenerateData(username);
        LOGGER.debug("intent Id from the requested claims '{}'", intentId);
        return intentTypeService.consentDetails(intentId, consentRequestJwt, accounts, username, clientId);
    } catch (ParseException e) {
        LOGGER.error("Could not parse the JWT", e);
        throw new OBErrorException(OBRIErrorType.RCS_CONSENT_REQUEST_FORMAT);
    } catch (OBErrorException e) {
        return rcsErrorService.invalidConsentError(consentRequestJwt, e);
    }
}
Also used : Claims(com.forgerock.openbanking.model.claim.Claims) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) SignedJWT(com.nimbusds.jwt.SignedJWT) ParseException(java.text.ParseException) AccountWithBalance(com.forgerock.openbanking.common.model.openbanking.persistence.account.AccountWithBalance)

Example 30 with OBErrorException

use of com.forgerock.openbanking.exceptions.OBErrorException in project openbanking-aspsp by OpenBankingToolkit.

the class AutodecisionsApiController method autoAccept.

@Override
public ResponseEntity<RedirectionAction> autoAccept(@RequestBody String consentRequestJwt, @CookieValue(value = "${am.cookie.name}") String ssoToken) throws OBErrorException {
    try {
        log.debug("Parse consent request JWS");
        SignedJWT signedJWT = (SignedJWT) JWTParser.parse(consentRequestJwt);
        log.debug("Read payment ID from the claims");
        // Read the claims
        Claims claims = JwsClaimsUtils.getClaims(signedJWT);
        if (!claims.getIdTokenClaims().containsKey(OpenBankingConstants.IdTokenClaim.INTENT_ID)) {
            return rcsErrorService.error(OBRIErrorType.RCS_CONSENT_REQUEST_INVALID, "No intent ID");
        }
        String intentId = claims.getIdTokenClaims().get(OpenBankingConstants.IdTokenClaim.INTENT_ID).getValue();
        String clientId = signedJWT.getJWTClaimsSet().getStringClaim(RCSConstants.Claims.CLIENT_ID);
        String redirectUri = signedJWT.getJWTClaimsSet().getStringClaim(OIDCConstants.OIDCClaim.CONSENT_APPROVAL_REDIRECT_URI);
        String csrf = signedJWT.getJWTClaimsSet().getStringClaim(RCSConstants.Claims.CSRF);
        List<String> scopes = new ArrayList<>(signedJWT.getJWTClaimsSet().getJSONObjectClaim(RCSConstants.Claims.SCOPES).keySet());
        Map<String, String> profile = userProfileService.getProfile(ssoToken, amOpenBankingConfiguration.endpointUserProfile, amOpenBankingConfiguration.cookieName);
        String username = profile.get(amOpenBankingConfiguration.userProfileId);
        List<FRAccount> accounts = getAccountOrGenerateData(username);
        // Call the right decision delegate, cased on the intent type
        ConsentDecisionDelegate consentDecisionDelegate = intentTypeService.getConsentDecision(intentId);
        consentDecisionDelegate.autoaccept(accounts, username);
        log.debug("Redirect the resource owner to the original oauth2/openid request but this time, with the " + "consent response jwt '{}'.", consentRequestJwt);
        String consentJwt = rcsService.generateRCSConsentResponse(rcsConfiguration, amOpenBankingConfiguration, csrf, true, scopes, clientId);
        ResponseEntity responseEntity = rcsService.sendRCSResponseToAM(ssoToken, RedirectionAction.builder().redirectUri(redirectUri).consentJwt(consentJwt).requestMethod(HttpMethod.POST).build());
        log.debug("Response received from AM: {}", responseEntity);
        if (responseEntity.getStatusCode() != HttpStatus.FOUND) {
            log.error("When sending the consent response {} to AM, it failed to returned a 302", consentJwt, responseEntity);
            throw new OBErrorException(OBRIErrorType.RCS_CONSENT_RESPONSE_FAILURE);
        }
        // TODO: Determine if the id_token needs re-writing!
        String location = responseEntity.getHeaders().getFirst(HttpHeaders.LOCATION);
        log.debug("The redirection to the consent page should be in the location '{}'", location);
        return ResponseEntity.ok(RedirectionAction.builder().redirectUri(location).build());
    } catch (JOSEException e) {
        log.error("Could not generate consent context JWT", e);
        throw new OBErrorException(OBRIErrorType.RCS_CONSENT_RESPONSE_FAILURE);
    } catch (ParseException e) {
        log.error("Could not parse the JWT", e);
        throw new OBErrorException(OBRIErrorType.RCS_CONSENT_REQUEST_FORMAT);
    } catch (Exception e) {
        log.error("Unexpected error while authorising consent", e);
        throw new OBErrorException(OBRIErrorType.RCS_CONSENT_RESPONSE_FAILURE);
    }
}
Also used : Claims(com.forgerock.openbanking.model.claim.Claims) FRAccount(com.forgerock.openbanking.common.model.openbanking.persistence.account.FRAccount) ArrayList(java.util.ArrayList) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) SignedJWT(com.nimbusds.jwt.SignedJWT) JOSEException(com.nimbusds.jose.JOSEException) ParseException(java.text.ParseException) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) HttpClientErrorException(org.springframework.web.client.HttpClientErrorException) ResponseEntity(org.springframework.http.ResponseEntity) ConsentDecisionDelegate(com.forgerock.openbanking.aspsp.rs.rcs.api.rcs.decisions.ConsentDecisionDelegate) ParseException(java.text.ParseException) JOSEException(com.nimbusds.jose.JOSEException)

Aggregations

OBErrorException (com.forgerock.openbanking.exceptions.OBErrorException)69 Test (org.junit.Test)20 ParseException (java.text.ParseException)19 IOException (java.io.IOException)13 OBErrorResponseException (com.forgerock.openbanking.exceptions.OBErrorResponseException)9 SignedJWT (com.nimbusds.jwt.SignedJWT)9 ResponseEntity (org.springframework.http.ResponseEntity)9 InvalidTokenException (com.forgerock.openbanking.jwt.exceptions.InvalidTokenException)8 Tpp (com.forgerock.openbanking.model.Tpp)8 HttpClientErrorException (org.springframework.web.client.HttpClientErrorException)6 PaymentConsent (com.forgerock.openbanking.common.model.openbanking.persistence.payment.PaymentConsent)5 List (java.util.List)5 HttpServletRequest (javax.servlet.http.HttpServletRequest)5 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)4 AccountRequest (com.forgerock.openbanking.common.model.openbanking.persistence.account.AccountRequest)4 OIDCConstants (com.forgerock.openbanking.constants.OIDCConstants)4 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)4 PermissionDenyException (com.forgerock.openbanking.common.error.exception.PermissionDenyException)3 OAuth2BearerTokenUsageInvalidTokenException (com.forgerock.openbanking.common.error.exception.oauth2.OAuth2BearerTokenUsageInvalidTokenException)3 OAuth2InvalidClientException (com.forgerock.openbanking.common.error.exception.oauth2.OAuth2InvalidClientException)3