use of com.forgerock.openbanking.model.claim.Claims in project openbanking-aspsp by OpenBankingToolkit.
the class JwsClaimsUtils method getClaims.
/**
* getClaims extracts the claims from a JWT
*
* @param signedJWT the JWT from which the claims are to be returned
* @return a {@code Claims} object containing the claims extracted from {@code signedJWT}
* @throws ParseException
*/
public static Claims getClaims(SignedJWT signedJWT) throws ParseException {
JWTClaimsSet claimSet = signedJWT.getJWTClaimsSet();
Map<String, Object> jsonClaimSet = claimSet.getJSONObjectClaim(OIDCConstants.OIDCClaim.CLAIMS);
Claims claims = Claims.parseClaims(new JSONObject(jsonClaimSet));
return claims;
}
use of com.forgerock.openbanking.model.claim.Claims 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);
}
}
use of com.forgerock.openbanking.model.claim.Claims 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);
}
}
use of com.forgerock.openbanking.model.claim.Claims in project openbanking-aspsp by OpenBankingToolkit.
the class RCSConsentDecisionApiController method decision.
/**
* @param consentDecisionSerialised
* @param ssoToken
* @return
* @throws OBErrorException
*/
@Override
public ResponseEntity decision(@RequestBody String consentDecisionSerialised, @CookieValue(value = "${am.cookie.name}") String ssoToken) throws OBErrorException {
log.debug("decisionAccountSharing() consentDecisionSerialised is {}", consentDecisionSerialised);
// Send a Consent response JWT to the initial request, which is define in the code
if (consentDecisionSerialised == null || consentDecisionSerialised.isEmpty()) {
log.debug("Consent decision is empty");
return rcsErrorService.error(OBRIErrorType.RCS_CONSENT_DECISION_EMPTY);
}
ConsentDecision consentDecision;
try {
consentDecision = objectMapper.readValue(consentDecisionSerialised, ConsentDecision.class);
} catch (IOException e) {
log.error("Remote consent decisions invalid", e);
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_DECISIONS_FORMAT, e.getMessage());
}
String consentRequestJwt = consentDecision.getConsentJwt();
if (consentRequestJwt == null || consentRequestJwt.isEmpty() || consentRequestJwt.isBlank()) {
log.error("Remote consent decisions invalid - consentRequestJwt is null ");
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_DECISIONS_FORMAT, "consentRequestJwt was null or " + "empty");
}
try {
try {
log.debug("Received an accept consent request");
// TODO check token but ignore if it's expired
// cryptoApiClient.validateJws(consentDecision.getConsentJwt(),
// amOpenBankingConfiguration.getIssuerID(), amOpenBankingConfiguration.jwksUri);
SignedJWT consentContextJwt = (SignedJWT) JWTParser.parse(consentRequestJwt);
boolean decision = RCSConstants.Decision.ALLOW.equals(consentDecision.getDecision());
log.debug("The decision is '{}'", decision);
// here is a good time to actually save that the consent has been approved by our resource owner
Claims claims = JwsClaimsUtils.getClaims(consentContextJwt);
String intentId = claims.getIdTokenClaims().get(OpenBankingConstants.IdTokenClaim.INTENT_ID).getValue();
String csrf = consentContextJwt.getJWTClaimsSet().getStringClaim(RCSConstants.Claims.CSRF);
String clientId = consentContextJwt.getJWTClaimsSet().getStringClaim(RCSConstants.Claims.CLIENT_ID);
List<String> scopes = new ArrayList<>(consentContextJwt.getJWTClaimsSet().getJSONObjectClaim(RCSConstants.Claims.SCOPES).keySet());
String redirectUri = consentContextJwt.getJWTClaimsSet().getStringClaim(OIDCConstants.OIDCClaim.CONSENT_APPROVAL_REDIRECT_URI);
ConsentDecisionDelegate consentDecisionDelegate = intentTypeService.getConsentDecision(intentId);
if (consentDecisionDelegate == null) {
log.error("No Consent Decision Delegate available from the intent type Service.");
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_REQUEST_INVALID, "Invalid intent ID? '" + intentId + "'");
}
// Verify consent is own by the right TPP
String tppIdBehindConsent = consentDecisionDelegate.getTppIdBehindConsent();
Optional<Tpp> isTpp = tppStoreService.findById(tppIdBehindConsent);
if (isTpp.isEmpty()) {
log.error("The TPP '{}' that created this intent id '{}' doesn't exist anymore.", tppIdBehindConsent, intentId);
return rcsErrorService.error(OBRIErrorType.RCS_CONSENT_REQUEST_NOT_FOUND_TPP, tppIdBehindConsent, intentId, clientId);
}
if (!clientId.equals(isTpp.get().getClientId())) {
log.error("The TPP '{}' created the account request '{}' but it's TPP '{}' that is trying to get" + " consent for it.", tppIdBehindConsent, intentId, clientId);
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_REQUEST_INVALID_CONSENT, tppIdBehindConsent, intentId, clientId);
}
// Verify consent decision is send by the same user
Map<String, String> profile = userProfileService.getProfile(ssoToken, amOpenBankingConfiguration.endpointUserProfile, amOpenBankingConfiguration.cookieName);
String username = profile.get(amOpenBankingConfiguration.userProfileId);
String userIdBehindConsent = consentDecisionDelegate.getUserIDBehindConsent();
if (!username.equals(userIdBehindConsent)) {
log.error("The consent was associated with user '{}' but now, its user '{}' that " + "send the consent decision.", userIdBehindConsent, username);
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_DECISION_INVALID_USER, userIdBehindConsent, username);
}
// Call the right decision delegate, cased on the intent type
consentDecisionDelegate.consentDecision(consentDecisionSerialised, decision);
log.debug("Redirect the resource owner to the original oauth2/openid request but this time, with the " + "consent response jwt '{}'.", consentContextJwt.toString());
String consentJwt = rcsService.generateRCSConsentResponse(rcsConfiguration, amOpenBankingConfiguration, csrf, decision, 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. response '{}' ", consentJwt, responseEntity);
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_RESPONSE_FAILURE);
} else if (locationContainsError(responseEntity.getHeaders().getLocation())) {
log.error("When sending the consent response {} to AM, it failed. response '{}' ", consentJwt, responseEntity);
return rcsErrorService.invalidConsentError(responseEntity.getHeaders().getLocation());
}
ResponseEntity rewrittenResponseEntity = null;
try {
rewrittenResponseEntity = jwtOverridingService.rewriteIdTokenFragmentInLocationHeader(responseEntity);
} catch (AccessTokenReWriteException e) {
log.info("decisionAccountSharing() Failed to re-write id_token", e);
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_RESPONSE_FAILURE);
}
String location = rewrittenResponseEntity.getHeaders().getFirst("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 (IOException e) {
log.error("Remote consent decisions invalid", e);
throw new OBErrorException(OBRIErrorType.RCS_CONSENT_DECISIONS_FORMAT, e.getMessage());
}
} catch (OBErrorException e) {
return rcsErrorService.invalidConsentError(consentRequestJwt, e);
}
}
Aggregations