use of com.forgerock.openbanking.exceptions.OBErrorResponseException in project openbanking-aspsp by OpenBankingToolkit.
the class HeadLessAuthorisationService method getConsentRequest.
private String getConsentRequest(AMGateway amGateway, String amAuthorizationEndpoint, AMAuthentication.TokenResponse authenticate) throws OBErrorResponseException, WrongResponseEntity {
// Send the request to AM which will ask us to redirect to the RCS
HttpHeaders amHeader = new HttpHeaders();
amHeader.add("Cookie", cookieName + "=" + authenticate.getTokenId());
ResponseEntity<String> responseEntity = null;
try {
responseEntity = amGateway.toAM(amAuthorizationEndpoint, HttpMethod.GET, amHeader, new ParameterizedTypeReference<String>() {
}, null);
log.debug("Response received by AM: {}", responseEntity);
} catch (Exception e) {
log.error("getConsentRequest() Caught exception from AM.", e);
throw new OBErrorResponseException(OBRIErrorType.HEAD_LESS_AUTH_AS_ERROR_RECEIVED.getHttpStatus(), OBRIErrorResponseCategory.HEADLESS_AUTH, OBRIErrorType.HEAD_LESS_AUTH_AS_ERROR_RECEIVED.toOBError1(e.getMessage()));
}
if (responseEntity.getStatusCode() != HttpStatus.FOUND) {
throw new WrongResponseEntity(responseEntity);
}
// Extract the RCS consent
String location = responseEntity.getHeaders().getFirst(HttpHeaders.LOCATION);
log.debug("The redirection to the consent page should be in the location '{}'", location);
try {
URL url = new URL(location);
Map<String, String> queryParameters = ParseUriUtils.parseQueryOrFragment(url.getQuery());
if (!queryParameters.containsKey("consent_request")) {
throw new WrongResponseEntity(responseEntity);
}
log.debug("The consent_request '{}'", queryParameters.get("consent_request"));
return queryParameters.get("consent_request");
} catch (MalformedURLException e) {
log.error("The location '{}' to the RCS, returned by AM, is not an URL", location, e);
throw new OBErrorResponseException(OBRIErrorType.HEAD_LESS_AUTH_RCS_URI_INCORRECT.getHttpStatus(), OBRIErrorResponseCategory.HEADLESS_AUTH, OBRIErrorType.HEAD_LESS_AUTH_RCS_URI_INCORRECT.toOBError1(location));
}
}
use of com.forgerock.openbanking.exceptions.OBErrorResponseException in project openbanking-aspsp by OpenBankingToolkit.
the class AccessTokenApiControllerTest method failsWhenNoClientCredentials_getAccessToken.
@Test
public void failsWhenNoClientCredentials_getAccessToken() throws OBErrorResponseException {
// Given
MultiValueMap<String, String> params = getParamsMap(CLIENT_CREDENTIAL);
PairClientIDAuthMethod pairClientIDAuthMethod = getClientIDAuthMethod(TokenEndpointAuthMethods.PRIVATE_KEY_JWT);
given(matlsRequestVerificationService.verifyMATLSMatchesRequest(params, authorization, principal)).willReturn(pairClientIDAuthMethod);
// When
OBErrorResponseException e = catchThrowableOfType(() -> this.accessTokenApiController.getAccessToken(params, authorization, principal, request), OBErrorResponseException.class);
// Then
assertThat(e).isNotNull();
assertThat(e.getStatus()).isEqualTo(HttpStatus.UNAUTHORIZED);
assertThat(e.getCategory()).isEqualTo(OBRIErrorResponseCategory.ACCESS_TOKEN);
}
use of com.forgerock.openbanking.exceptions.OBErrorResponseException in project openbanking-aspsp by OpenBankingToolkit.
the class MatlsRequestVerificationService method getPairClientIdAuthMethodFromClientAssertion.
private PairClientIDAuthMethod getPairClientIdAuthMethodFromClientAssertion(String clientAssertion, MultiValueMap paramMap) throws OBErrorResponseException {
PairClientIDAuthMethod pairClientIDAuthMethod = new PairClientIDAuthMethod();
if (clientAssertion == null || clientAssertion.isEmpty() || clientAssertion.isBlank()) {
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_INVALID.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_INVALID.toOBError1("No client_assertion in body"));
}
log.debug("Read client ID from client assertion found: {}", clientAssertion);
try {
SignedJWT jws = (SignedJWT) JWTParser.parse(clientAssertion);
pairClientIDAuthMethod.clientId = jws.getJWTClaimsSet().getSubject();
Object clientIDFromBody = paramMap.getFirst(CLIENT_ID);
if (clientIDFromBody != null && !pairClientIDAuthMethod.clientId.equals(clientIDFromBody)) {
log.error("Client ID from the request body {} is not matching the client assertion sub {}", clientIDFromBody, pairClientIDAuthMethod.clientId);
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_CLIENT_ID_MISS_MATCH.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_CLIENT_ID_MISS_MATCH.toOBError1(clientIDFromBody, pairClientIDAuthMethod.clientId));
}
pairClientIDAuthMethod.authMethod = OIDCConstants.TokenEndpointAuthMethods.PRIVATE_KEY_JWT;
} catch (ParseException e) {
log.error("Parse client assertion error", e);
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_CLIENT_ASSERTION_FORMAT_INVALID.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_CLIENT_ASSERTION_FORMAT_INVALID.toOBError1(clientAssertion));
}
return pairClientIDAuthMethod;
}
use of com.forgerock.openbanking.exceptions.OBErrorResponseException in project openbanking-aspsp by OpenBankingToolkit.
the class MatlsRequestVerificationService method verifyMATLSMatchesRequest.
public PairClientIDAuthMethod verifyMATLSMatchesRequest(MultiValueMap paramMap, String authorization, Principal principal) throws OBErrorResponseException {
UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal();
PairClientIDAuthMethod pairClientIDAuthMethod;
String clientAssertion = (String) paramMap.getFirst(OIDCConstants.OIDCClaim.CLIENT_ASSERTION);
if (clientAssertion != null) {
pairClientIDAuthMethod = getPairClientIdAuthMethodFromClientAssertion(clientAssertion, paramMap);
} else if (authorization != null) {
pairClientIDAuthMethod = getPairClientIdAuthMethodFromAuthorization(authorization, paramMap);
} else if (paramMap.get("client_secret") != null) {
pairClientIDAuthMethod = getPairClientIdAuthMethodWhenClientSecret(paramMap);
} else {
pairClientIDAuthMethod = getPairClientIdAuthMethodDefault(paramMap);
}
String authClientId = pairClientIDAuthMethod.clientId;
Tpp tpp = getTppRegistered(authClientId);
if (!matlsIdMatchesTppId(principal.getName(), tpp)) {
log.info("The clientId found via the authentication method did not belong to the Tpp identified by the " + "MATLS certificate's principal (authorisationNumber). authorisationNumber '{}', clientId '{}'", principal.getName(), tpp.getAuthorisationNumber());
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_CREDENTIAL_NOT_MATCHING_CLIENT_CERTS.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_CREDENTIAL_NOT_MATCHING_CLIENT_CERTS.toOBError1(tpp.getClientId(), pairClientIDAuthMethod.clientId, pairClientIDAuthMethod.authMethod.type));
}
// can throw UnsupportedOIDCAuthMethodsException
OIDCRegistrationResponse registrationResponse = tpp.getRegistrationResponse();
String tokenEndpointAuthMethod = registrationResponse.getTokenEndpointAuthMethod();
OIDCConstants.TokenEndpointAuthMethods authMethodsFromTpp = OIDCConstants.TokenEndpointAuthMethods.fromType(tokenEndpointAuthMethod);
if (!authMethodsFromTpp.equals(pairClientIDAuthMethod.authMethod)) {
log.info("The authorisation method specified in the token differend from that in the Tpp registration " + "response");
throw new OBErrorResponseException(OBRIErrorType.ACCESS_TOKEN_WRONG_AUTH_METHOD.getHttpStatus(), OBRIErrorResponseCategory.ACCESS_TOKEN, OBRIErrorType.ACCESS_TOKEN_WRONG_AUTH_METHOD.toOBError1(pairClientIDAuthMethod.authMethod.type, authMethodsFromTpp.type));
}
return pairClientIDAuthMethod;
}
use of com.forgerock.openbanking.exceptions.OBErrorResponseException in project openbanking-aspsp by OpenBankingToolkit.
the class DiscoveryApiController method getDiscovery.
@Override
public ResponseEntity getDiscovery(HttpServletRequest request) throws OBErrorResponseException {
String normalEndpoint = "https://as.aspsp." + dnsHostRoot;
String matlsProtectedEndpoint = withPort("https://matls.as.aspsp." + dnsHostRoot);
HttpHeaders additionalHttpHeaders = new HttpHeaders();
ParameterizedTypeReference<OIDCDiscoveryResponse> ptr = new ParameterizedTypeReference<OIDCDiscoveryResponse>() {
};
ResponseEntity<OIDCDiscoveryResponse> responseEntity = amGateway.toAM(request, additionalHttpHeaders, ptr);
OIDCDiscoveryResponse discoveryResponse = Objects.requireNonNull(responseEntity.getBody());
log.debug("Discovery response received from AM: {}", discoveryResponse);
discoveryResponse.setVersion(readWriteApiVersion);
discoveryResponse.setReadWriteApiVersion(readWriteApiVersion);
discoveryResponse.setClientRegistrationApiVersion(clientRegistrationApiVersion);
// Override the well-known
discoveryResponse.setIssuer(switchToNonMatls(discoveryResponse.getIssuer()));
discoveryResponse.setIntrospectionEndpoint(switchToSCGWPort(switchToMatls(discoveryResponse.getIntrospectionEndpoint())));
discoveryResponse.setUserinfoEndpoint(switchToSCGWPort(switchToMatls(discoveryResponse.getUserinfoEndpoint())));
discoveryResponse.setTokenEndpoint(switchToSCGWPort(switchToMatls(discoveryResponse.getTokenEndpoint())));
if (discoveryConfig.getObieJwkUri() != null && !"".equals(discoveryConfig.getObieJwkUri())) {
discoveryResponse.setJwksUri(discoveryConfig.getObieJwkUri());
} else {
discoveryResponse.setJwksUri(withPort(normalEndpoint) + "/api/jwk/jwk_uri");
}
discoveryResponse.setAuthorizationEndpoint(withPort(normalEndpoint) + "/oauth2/authorize");
log.debug("Supported Token Endpoint Auth Methods from AM: {} will be restricted to as-api configured values: {}", discoveryResponse.getTokenEndpointAuthMethodsSupported(), discoveryConfig.getSupportedAuthMethod());
discoveryResponse.setTokenEndpointAuthMethodsSupported(discoveryConfig.getSupportedAuthMethod());
log.debug("Grant Types from AM: {} will be restricted to as-api configured values: {}", discoveryResponse.getGrantTypesSupported(), discoveryConfig.getSupportedGrantTypes());
discoveryResponse.setGrantTypesSupported(discoveryConfig.getSupportedGrantTypes());
// FAPI compliant ('code id_token'): https://github.com/ForgeCloud/ob-deploy/issues/674
if (discoveryResponse.getResponseTypesSupported().containsAll(discoveryConfig.getSupportedResponseTypes())) {
log.debug("Response Types from AM: {} will be restricted to as-api configured values: {}", discoveryResponse.getResponseTypesSupported(), discoveryConfig.getSupportedResponseTypes());
discoveryResponse.setResponseTypesSupported(discoveryConfig.getSupportedResponseTypes());
} else {
log.error("The response types supported by the authorisation server '" + discoveryResponse.getResponseTypesSupported() + "' don't match with the response types supported '" + discoveryConfig.getSupportedResponseTypes() + "' by as-api");
throw new OBErrorResponseException(OBRIErrorType.DISCOVERY_RESPONSE_TYPE_MISMATCH.getHttpStatus(), OBRIErrorResponseCategory.REQUEST_INVALID, OBRIErrorType.DISCOVERY_RESPONSE_TYPE_MISMATCH.toOBError1(discoveryResponse.getResponseTypesSupported().toString(), discoveryConfig.getSupportedResponseTypes().toString()));
}
log.debug("Set requestUriParameterSupported={} from as-api config", discoveryConfig.isRequestUriParameterSupported());
discoveryResponse.setRequestUriParameterSupported(discoveryConfig.isRequestUriParameterSupported());
if (discoveryConfig.isDynamicRegistrationEnable()) {
discoveryResponse.setRegistrationEndpoint(matlsProtectedEndpoint + "/open-banking/register/");
} else {
log.debug("Dynamic Registration disabled. Registration endpoint will not appear in the well-known endpoint response.");
discoveryResponse.setRegistrationEndpoint(null);
}
if (discoveryConfig.isUserInfoEnable()) {
discoveryResponse.setUserinfoEndpoint(switchToSCGWPort(switchToMatls(discoveryResponse.getUserinfoEndpoint())));
} else {
log.debug("User Info endpoint disabled. It will not appear in the well-known endpoint response.");
discoveryResponse.setUserinfoEndpoint(null);
discoveryResponse.setUserinfoEncryptionAlgValuesSupported(null);
discoveryResponse.setUserinfoEncryptionEncValuesSupported(null);
discoveryResponse.setUserinfoSigningAlgValuesSupported(null);
}
if (discoveryConfig.isIntrospectionEnable()) {
discoveryResponse.setIntrospectionEndpoint(switchToSCGWPort(switchToMatls(discoveryResponse.getIntrospectionEndpoint())));
} else {
log.debug("Introspection endpoint disabled. It will not appear in the well-known endpoint response.");
discoveryResponse.setIntrospectionEndpoint(null);
}
// Don't show empty fields in response
if (CollectionUtils.isEmpty(discoveryResponse.getIdTokenSigningAlgValuesSupported())) {
discoveryResponse.setIdTokenSigningAlgValuesSupported(null);
}
if (!discoveryConfig.isIdTokenEncryptionAlgValuesEnabled() || CollectionUtils.isEmpty(discoveryResponse.getIdTokenEncryptionAlgValuesSupported())) {
discoveryResponse.setIdTokenEncryptionAlgValuesSupported(null);
}
if (!discoveryConfig.isIdTokenEncryptionEncValuesEnabled() || CollectionUtils.isEmpty(discoveryResponse.getIdTokenEncryptionEncValuesSupported())) {
discoveryResponse.setIdTokenEncryptionEncValuesSupported(null);
}
if (CollectionUtils.isEmpty(discoveryResponse.getRequestObjectSigningAlgValuesSupported())) {
discoveryResponse.setRequestObjectSigningAlgValuesSupported(null);
}
if (!discoveryConfig.isRequestObjectEncryptionAlgValuesEnabled() || CollectionUtils.isEmpty(discoveryResponse.getRequestObjectEncryptionAlgValuesSupported())) {
discoveryResponse.setRequestObjectEncryptionAlgValuesSupported(null);
}
if (!discoveryConfig.isRequestObjectEncryptionEncValuesEnabled() || CollectionUtils.isEmpty(discoveryResponse.getRequestObjectEncryptionEncValuesSupported())) {
discoveryResponse.setRequestObjectEncryptionEncValuesSupported(null);
}
if (CollectionUtils.isEmpty(discoveryResponse.getTokenEndpointAuthSigningAlgValuesSupported())) {
discoveryResponse.setTokenEndpointAuthSigningAlgValuesSupported(null);
}
// If 'Request Uri Parameter' not active then don't show 'Require Request Uri Registration' value as it is not relevant to our API
if (!discoveryResponse.getRequestUriParameterSupported()) {
discoveryResponse.setRequireRequestUriRegistration(null);
}
log.debug("Discovery response after manipulation: {}", discoveryResponse);
return ResponseEntity.ok(discoveryResponse);
}
Aggregations