Search in sources :

Example 1 with InvalidTokenException

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

the class TppRegistrationService method validateSsaAgainstIssuingDirectoryJwksUri.

public String validateSsaAgainstIssuingDirectoryJwksUri(String ssaSerialised, String issuer) throws DynamicClientRegistrationException {
    log.debug("validateSsaAgainstIssuingDirectoryJwksUri(): issuer is {}", issuer);
    if (ssaSerialised == null) {
        return null;
    }
    if (issuer.equals(openBankingDirectoryConfiguration.issuerId)) {
        try {
            log.debug("validateSsaAgainstIssuingDirectoryJwksUri() Verify the SSA against OB directory");
            cryptoApiClient.validateJws(ssaSerialised, openBankingDirectoryConfiguration.getIssuerID(), openBankingDirectoryConfiguration.jwksUri);
            return openBankingDirectoryConfiguration.id;
        } catch (InvalidTokenException | HttpClientErrorException | ParseException | IOException e) {
            log.debug("validateSsaAgainstIssuingDirectoryJwksUri() Invalid SSA signature from OB directory", e);
        }
    } else if (issuer.equals(forgeRockDirectoryConfiguration.getIssuerID())) {
        try {
            log.debug("validateSsaAgainstIssuingDirectoryJwksUri() Verify the SSA against ForgeRock directory");
            cryptoApiClient.validateJws(ssaSerialised, null, forgeRockDirectoryConfiguration.jwksUri);
            return forgeRockDirectoryConfiguration.id;
        } catch (InvalidTokenException | ParseException | IOException e) {
            log.debug("validateSsaAgainstIssuingDirectoryJwksUri() Invalid SSA signature from ForgeRock directory", e);
        }
    } else {
        String errorMessage = "Unrecognised ssa. Issuer is '" + issuer + "'. Please use an Open Banking issued " + "SSA.";
        log.debug("validateSsaAgainstIssuingDirectoryJwksUri() {}", errorMessage);
        throw new DynamicClientRegistrationException(errorMessage, DynamicClientRegistrationErrorType.UNAPPROVED_SOFTWARE_STATEMENT);
    }
    return null;
}
Also used : OAuth2BearerTokenUsageInvalidTokenException(com.forgerock.openbanking.common.error.exception.oauth2.OAuth2BearerTokenUsageInvalidTokenException) InvalidTokenException(com.forgerock.openbanking.jwt.exceptions.InvalidTokenException) HttpClientErrorException(org.springframework.web.client.HttpClientErrorException) DynamicClientRegistrationException(com.forgerock.openbanking.common.error.exception.dynamicclientregistration.DynamicClientRegistrationException) ParseException(java.text.ParseException) IOException(java.io.IOException)

Example 2 with InvalidTokenException

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

the class DetachedJwsVerifier method verifyDetachedJws.

public void verifyDetachedJws(String detachedJws, OBVersion obVersion, HttpServletRequest request, String oauth2ClientId) throws OBErrorException {
    if (StringUtils.isEmpty(detachedJws)) {
        log.warn("Detached signature not provided");
        throw new OBErrorException(OBRIErrorType.DETACHED_JWS_INVALID, detachedJws, "Not provided");
    }
    try {
        MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest(request);
        String body = multiReadRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        log.debug("Verify detached signature {} with payload {}", detachedJws, body);
        // obVersion is only set from 3.1.3 onwards
        if ((obVersion == null || obVersion.isBeforeVersion(v3_1_4)) && isBase64Encoded(detachedJws)) {
            log.warn("Invalid detached signature {}, {}", detachedJws, "b64 claim header not set to false in version: " + obVersion);
            throw new OBErrorException(OBRIErrorType.DETACHED_JWS_INVALID, detachedJws, "b64 claim header not set to false");
        }
        if (obVersion != null && obVersion.isAfterVersion(v3_1_3) && isB64ClaimHeaderPresent(detachedJws)) {
            log.warn("Invalid detached signature {}, {}", detachedJws, "b64 claim header must not be present in version: " + obVersion);
            throw new OBErrorException(OBRIErrorType.DETACHED_JWS_INVALID, detachedJws, "b64 claim header must not be present");
        }
        Tpp tpp = tppStoreService.findByClientId(oauth2ClientId).get();
        DirectorySoftwareStatement softwareStatement = tpp.getDirectorySoftwareStatement();
        String orgId = softwareStatement.getOrg_id();
        String softwareId = softwareStatement.getSoftware_id();
        String expectedIssuer = orgId + "/" + softwareId;
        if (tpp.getRegistrationResponse().getJwks() != null) {
            cryptoApiClient.validateDetachedJWSWithJWK(detachedJws, body, null, expectedIssuer, tpp.getRegistrationResponse().getJwks().getKeys().get(0));
        } else {
            cryptoApiClient.validateDetachedJWS(detachedJws, body, null, expectedIssuer, tpp.getRegistrationResponse().getJwks_uri());
        }
    } catch (InvalidTokenException e) {
        log.warn("Invalid detached signature {}", detachedJws, e);
        throw new OBErrorException(OBRIErrorType.DETACHED_JWS_INVALID, detachedJws, e.getMessage());
    } catch (IOException e) {
        log.error("Can't get the request body", e);
        throw new OBErrorException(OBRIErrorType.DETACHED_JWS_UN_ACCESSIBLE);
    } catch (ParseException e) {
        log.error("Can't parse JWS", e);
        throw new OBErrorException(OBRIErrorType.DETACHED_JWS_INVALID, detachedJws, e.getMessage());
    }
}
Also used : InvalidTokenException(com.forgerock.openbanking.jwt.exceptions.InvalidTokenException) MultiReadHttpServletRequest(com.forgerock.openbanking.aspsp.rs.filter.MultiReadHttpServletRequest) Tpp(com.forgerock.openbanking.model.Tpp) DirectorySoftwareStatement(com.forgerock.openbanking.model.DirectorySoftwareStatement) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) IOException(java.io.IOException) ParseException(java.text.ParseException)

Example 3 with InvalidTokenException

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

the class AuthorisationApiController method validateRequestParameter.

private SignedJWT validateRequestParameter(String responseType, String clientId, String state, String nonce, String scopes, String redirectUri, String requestParametersSerialised) throws OBErrorException {
    SignedJWT requestParameters;
    try {
        try {
            EncryptedJWT.parse(requestParametersSerialised);
            log.debug("Request parameter {} is encrypted (JWE).", requestParametersSerialised);
            requestParameters = cryptoApiClient.decryptJwe(requestParametersSerialised);
            requestParametersSerialised = requestParameters.serialize();
            log.debug("Request parameter {} decrypted (JWS).", requestParametersSerialised);
        } catch (ParseException | JOSEException e) {
            // If we got an exception, it means it's a JWS
            log.debug("Request parameter {} is just signed (JWS).", requestParametersSerialised);
            requestParameters = SignedJWT.parse(requestParametersSerialised);
        }
        verifyQueryParameterMatchesRequestParameterClaim(requestParameters, "client_id", clientId);
        Optional<Tpp> byClientId = tppStoreService.findByClientId(clientId);
        if (byClientId.isEmpty()) {
            throw new OBErrorException(OBRIErrorType.REQUEST_PARAMETER_JWT_FORMAT_INVALID, "Unknown client id '" + clientId + "'");
        }
        Tpp tpp = byClientId.get();
        log.debug("Validate the request parameter signature");
        boolean validated = false;
        OIDCRegistrationResponse registrationResponse = tpp.getRegistrationResponse();
        if (registrationResponse != null) {
            JWKSet jwkSet = registrationResponse.getJwks();
            if (jwkSet != null) {
                List<JWK> jwkSetKeys = jwkSet.getKeys();
                if (jwkSetKeys != null && !jwkSetKeys.isEmpty()) {
                    JWK jwk = jwkSetKeys.get(0);
                    String jwksKeys = jwk.toString();
                    log.debug("validateRequestParameters() tpp has jwksKeys as part of registraiton. They will be" + " used to validate the request parameter.");
                    cryptoApiClient.validateJwsWithJWK(requestParametersSerialised, clientId, jwksKeys);
                    validated = true;
                } else {
                    log.debug("validateRequestParameter() tpp has no jwkSetKeys; {}", tpp);
                }
            }
            if (!validated) {
                String jwks_uri = tpp.getRegistrationResponse().getJwks_uri();
                if (jwks_uri == null || jwks_uri.isBlank()) {
                    log.error("validateRequestparameters() tpp does no have a jwksKeys, or a jwks_uri in it's " + "registration details; {}", tpp);
                    throw new InvalidTokenException("Tpp does no have a jwksKeys, or a jwks_uri in it's " + "registration details");
                } else {
                    log.debug("validateRequestParameter() Validating request parameter using jwks_uri: " + "requestParametersSerialised: '{}', clientId; '{}', jwks_url: {}", requestParametersSerialised, clientId, jwks_uri);
                    cryptoApiClient.validateJws(requestParametersSerialised, clientId, jwks_uri);
                    validated = true;
                }
            }
        } else {
            log.error("validateRequestParameter() tpp has no registration response; {}", tpp);
            throw new InvalidTokenException("Tpp is not registered");
        }
        List<String> MANDATORY_CLAIMS = Arrays.asList(OpenBankingConstants.RequestParameterClaim.AUD, OpenBankingConstants.RequestParameterClaim.SCOPE, OpenBankingConstants.RequestParameterClaim.ISS, OpenBankingConstants.RequestParameterClaim.CLAIMS, OpenBankingConstants.RequestParameterClaim.RESPONSE_TYPE, OpenBankingConstants.RequestParameterClaim.REDIRECT_URI, OpenBankingConstants.RequestParameterClaim.EXP, OpenBankingConstants.RequestParameterClaim.NONCE, OpenBankingConstants.RequestParameterClaim.CLIENT_ID);
        for (String mandatoryClaim : MANDATORY_CLAIMS) {
            if (requestParameters.getJWTClaimsSet().getClaim(mandatoryClaim) == null) {
                throw new OBErrorException(OBRIErrorType.REQUEST_PARAMETER_CLAIM_MANDATORY, mandatoryClaim);
            }
        }
        verifyQueryParameterMatchesRequestParameterClaim(requestParameters, "response_type", responseType);
        verifyQueryParameterMatchesRequestParameterClaim(requestParameters, "state", state);
        verifyQueryParameterMatchesRequestParameterClaim(requestParameters, "nonce", nonce);
        verifyQueryParameterMatchesRequestParameterClaim(requestParameters, "redirect_uri", redirectUri);
        verifyScopeQueryParameterMatchesRequestParameterClaim(requestParameters, scopes);
        verifyRequestparameterClaims(requestParameters);
    } catch (ParseException | IOException e) {
        log.error("Invalid Request parameter {}. Reason: {}", requestParametersSerialised, e.getMessage(), e);
        throw new OBErrorException(OBRIErrorType.REQUEST_PARAMETER_JWT_FORMAT_INVALID, e.getMessage());
    } catch (InvalidTokenException e) {
        log.error("Invalid Request parameter {}. Reason: {}", requestParametersSerialised, e.getMessage(), e);
        throw new OBErrorException(OBRIErrorType.REQUEST_PARAMETER_JWT_INVALID, e.getMessage());
    }
    return requestParameters;
}
Also used : InvalidTokenException(com.forgerock.openbanking.jwt.exceptions.InvalidTokenException) OIDCRegistrationResponse(com.forgerock.openbanking.model.oidc.OIDCRegistrationResponse) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) SignedJWT(com.nimbusds.jwt.SignedJWT) IOException(java.io.IOException) Tpp(com.forgerock.openbanking.model.Tpp) JWKSet(com.nimbusds.jose.jwk.JWKSet) ParseException(java.text.ParseException) JOSEException(com.nimbusds.jose.JOSEException) JWK(com.nimbusds.jose.jwk.JWK)

Example 4 with InvalidTokenException

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

the class RSEndpointWrapper method verifyAccessToken.

public void verifyAccessToken(List<String> expectedScopes, List<OIDCConstants.GrantType> expectedGrantTypes) throws OBErrorException {
    try {
        // Verify access token
        log.info("Verify the access token {}", authorization);
        accessToken = rsEndpointWrapperService.verifyAccessToken(authorization);
        String grantTypeSerialised = accessToken.getJWTClaimsSet().getStringClaim(OBConstants.OIDCClaim.GRANT_TYPE);
        if (grantTypeSerialised == null) {
            log.error("We managed to get an access token that doesn't have a grant type claim defined: {}", authorization);
            throw new OBErrorException(SERVER_ERROR, "Access token grant type is undefined");
        }
        OIDCConstants.GrantType grantType = OIDCConstants.GrantType.fromType(grantTypeSerialised);
        if (!OIDCConstants.GrantType.REFRESH_TOKEN.equals(grantType) && !expectedGrantTypes.contains(grantType)) {
            log.debug("The access token grant type {} doesn't match one of the expected grant types {}", grantType, expectedGrantTypes);
            throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID_GRANT_TYPE, grantType, expectedGrantTypes);
        }
        List<String> scopes = (List<String>) accessToken.getJWTClaimsSet().getClaim(OBConstants.OIDCClaim.SCOPE);
        if (!scopes.containsAll(expectedScopes)) {
            log.warn("The access token {} doesn't contain the scope {}", authorization, expectedScopes);
            throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID_SCOPE, expectedScopes);
        }
    } catch (ParseException e) {
        log.warn("Couldn't parse the the access token {}. It's probably not stateless and therefore, not " + "an access token generated by our ASPSP-AS", authorization);
        throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID_FORMAT);
    } catch (InvalidTokenException e) {
        log.warn("Invalid access token {}", authorization);
        throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID, e.getMessage());
    } catch (IOException e) {
        log.error("IO exception", e);
        throw new OBErrorException(SERVER_ERROR, e.getMessage());
    }
}
Also used : InvalidTokenException(com.forgerock.openbanking.jwt.exceptions.InvalidTokenException) OIDCConstants(com.forgerock.openbanking.constants.OIDCConstants) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) List(java.util.List) ParseException(java.text.ParseException) IOException(java.io.IOException)

Example 5 with InvalidTokenException

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

the class AggregatedPollingApiEndpointWrapper method verifyAccessToken.

@Override
public void verifyAccessToken(List<String> expectedScopes, List<OIDCConstants.GrantType> expectedGrantTypes) throws OBErrorException {
    try {
        // Verify access token
        log.info("Verify the access token {}", authorization);
        accessToken = rsEndpointWrapperService.amResourceServerService.verifyAccessToken(authorization);
        List<String> scopes = (List<String>) accessToken.getJWTClaimsSet().getClaim(OBConstants.OIDCClaim.SCOPE);
        String grantTypeSerialised = accessToken.getJWTClaimsSet().getStringClaim(OBConstants.OIDCClaim.GRANT_TYPE);
        if (grantTypeSerialised == null) {
            log.error("We managed to get an access token that doesn't have a grant type claim defined: {}", authorization);
            throw new OBErrorException(SERVER_ERROR, "Access token grant type is undefined");
        }
        OIDCConstants.GrantType grantType = OIDCConstants.GrantType.fromType(grantTypeSerialised);
        if (!OIDCConstants.GrantType.REFRESH_TOKEN.equals(grantType) && !expectedGrantTypes.contains(grantType)) {
            log.debug("The access token grant type {} doesn't match one of the expected grant types {}", grantType, expectedGrantTypes);
            throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID_GRANT_TYPE, grantType, expectedGrantTypes);
        }
        if (scopes.stream().noneMatch(expectedScopes::contains)) {
            log.warn("The access token {} contains scopes: {} but needs at least one of the expected scopes: {}", authorization, scopes, expectedScopes);
            throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID_SCOPE, expectedScopes);
        }
    } catch (ParseException e) {
        log.warn("Couldn't parse the the access token {}. It's probably not stateless and therefore, not " + "an access token generated by our ASPSP-AS", authorization);
        throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID_FORMAT);
    } catch (InvalidTokenException e) {
        log.warn("Invalid access token {}", authorization);
        throw new OBErrorException(OBRIErrorType.ACCESS_TOKEN_INVALID, e.getMessage());
    } catch (IOException e) {
        log.error("IO exception", e);
        throw new OBErrorException(SERVER_ERROR, e.getMessage());
    }
}
Also used : InvalidTokenException(com.forgerock.openbanking.jwt.exceptions.InvalidTokenException) OIDCConstants(com.forgerock.openbanking.constants.OIDCConstants) List(java.util.List) OBErrorException(com.forgerock.openbanking.exceptions.OBErrorException) ParseException(java.text.ParseException) IOException(java.io.IOException)

Aggregations

InvalidTokenException (com.forgerock.openbanking.jwt.exceptions.InvalidTokenException)8 IOException (java.io.IOException)8 ParseException (java.text.ParseException)8 OBErrorException (com.forgerock.openbanking.exceptions.OBErrorException)5 OAuth2BearerTokenUsageInvalidTokenException (com.forgerock.openbanking.common.error.exception.oauth2.OAuth2BearerTokenUsageInvalidTokenException)3 OIDCConstants (com.forgerock.openbanking.constants.OIDCConstants)3 List (java.util.List)3 DynamicClientRegistrationException (com.forgerock.openbanking.common.error.exception.dynamicclientregistration.DynamicClientRegistrationException)2 Tpp (com.forgerock.openbanking.model.Tpp)2 SignedJWT (com.nimbusds.jwt.SignedJWT)2 MultiReadHttpServletRequest (com.forgerock.openbanking.aspsp.rs.filter.MultiReadHttpServletRequest)1 DirectorySoftwareStatement (com.forgerock.openbanking.model.DirectorySoftwareStatement)1 OIDCRegistrationResponse (com.forgerock.openbanking.model.oidc.OIDCRegistrationResponse)1 JOSEException (com.nimbusds.jose.JOSEException)1 JWK (com.nimbusds.jose.jwk.JWK)1 JWKSet (com.nimbusds.jose.jwk.JWKSet)1 HttpClientErrorException (org.springframework.web.client.HttpClientErrorException)1