Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding DCR gateway implementation #227

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@
<artifactId>nimbus-jose-jwt</artifactId>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<groupId>org.json.wso2</groupId>
<artifactId>json</artifactId>
</dependency>
<!-- Test Dependencies -->
<dependency>
Expand Down Expand Up @@ -235,7 +235,7 @@
com.nimbusds.jose;version="${org.wso2.orbit.nimbus.version.range}",
com.nimbusds.jwt;version="${org.wso2.orbit.nimbus.version.range}",
javax.cache,
net.minidev.json;version="${json-smart.version}",
org.json;version="${org.json.version.range}",
org.apache.axiom.*;version="${axiom.osgi.version.range}",
org.apache.commons.lang3;version="${commons-lang3.version}",
org.apache.commons.logging;version="${commons.logging.version}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Stack;
Expand All @@ -63,8 +61,6 @@ public final class FinancialServicesConfigParser {
private final Map<String, Object> configuration = new HashMap<>();
private final Map<String, Map<Integer, String>> fsExecutors = new HashMap<>();
private final Map<String, Map<Integer, String>> authorizeSteps = new HashMap<>();
private final Map<String, List<String>> allowedScopes = new HashMap<>();
private final Map<String, List<String>> allowedAPIs = new HashMap<>();
private SecretResolver secretResolver;
private OMElement rootElement;
private static FinancialServicesConfigParser parser;
Expand Down Expand Up @@ -132,8 +128,6 @@ private void buildConfiguration() {
readChildElements(rootElement, nameStack);
buildFSExecutors();
buildConsentAuthSteps();
buildAllowedScopes();
buildAllowedSubscriptions();
} catch (IOException | XMLStreamException | OMException e) {
throw new FinancialServicesRuntimeException("Error occurred while building configuration from " +
"financial-services.xml", e);
Expand Down Expand Up @@ -297,74 +291,6 @@ private void readChildElements(OMElement serverConfig, Stack<String> nameStack)
}
}

private void buildAllowedScopes() {
OMElement gatewayElement = rootElement.getFirstChildWithName(
new QName(FinancialServicesConstants.FS_CONFIG_QNAME, FinancialServicesConstants.GATEWAY_CONFIG_TAG));

if (gatewayElement != null) {
OMElement tppManagementElement = gatewayElement.getFirstChildWithName(
new QName(FinancialServicesConstants.FS_CONFIG_QNAME,
FinancialServicesConstants.TPP_MANAGEMENT_CONFIG_TAG));

if (tppManagementElement != null) {
OMElement allowedScopesElement = tppManagementElement.getFirstChildWithName(new QName(
FinancialServicesConstants.FS_CONFIG_QNAME,
FinancialServicesConstants.ALLOWED_SCOPES_CONFIG_TAG));

// obtaining each scope under allowed scopes
Iterator environmentIterator = allowedScopesElement
.getChildrenWithLocalName(FinancialServicesConstants.SCOPE_CONFIG_TAG);

while (environmentIterator.hasNext()) {
OMElement scopeElem = (OMElement) environmentIterator.next();
String scopeName = scopeElem.getAttributeValue(new QName("name"));
String rolesStr = scopeElem.getAttributeValue(new QName("roles"));
if (StringUtils.isNotEmpty(rolesStr)) {
List<String> rolesList = Arrays.stream(rolesStr.split(","))
.map(String::trim)
.collect(Collectors.toList());
allowedScopes.put(scopeName, rolesList);
}
}
}
}
}

private void buildAllowedSubscriptions() {

OMElement dcrElement = rootElement.getFirstChildWithName(
new QName(FinancialServicesConstants.FS_CONFIG_QNAME, FinancialServicesConstants.DCR_CONFIG_TAG));

if (dcrElement != null) {
OMElement regulatoryAPIs = dcrElement.getFirstChildWithName(
new QName(FinancialServicesConstants.FS_CONFIG_QNAME,
FinancialServicesConstants.REGULATORY_API_NAMES));

if (regulatoryAPIs != null) {

// obtaining each regulatory API under allowed regulatory APIs
Iterator environmentIterator = regulatoryAPIs
.getChildrenWithLocalName(FinancialServicesConstants.REGULATORY_API);

while (environmentIterator.hasNext()) {
OMElement regulatoryAPIElem = (OMElement) environmentIterator.next();
String regulatoryAPIName = regulatoryAPIElem.getAttributeValue(new QName(
FinancialServicesConstants.API_NAME));
String rolesStr = regulatoryAPIElem.getAttributeValue(new QName(
FinancialServicesConstants.API_ROLE));
if (StringUtils.isNotEmpty(rolesStr)) {
List<String> rolesList = Arrays.stream(rolesStr.split(","))
.map(String::trim)
.collect(Collectors.toList());
allowedAPIs.put(regulatoryAPIName, rolesList);
} else {
allowedAPIs.put(regulatoryAPIName, Collections.emptyList());
}
}
}
}
}

/**
* Method to obtain config key from stack.
*
Expand Down Expand Up @@ -440,14 +366,6 @@ public Map<String, Map<Integer, String>> getConsentAuthorizeSteps() {
return Collections.unmodifiableMap(authorizeSteps);
}

public Map<String, List<String>> getAllowedScopes() {
return Collections.unmodifiableMap(allowedScopes);
}

public Map<String, List<String>> getAllowedAPIs() {
return Collections.unmodifiableMap(allowedAPIs);
}

public String getDataSourceName() {

Optional<String> source = getConfigurationFromKeyAsString(FinancialServicesConstants.JDBC_PERSISTENCE_CONFIG);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package org.wso2.financial.services.accelerator.common.config;

import java.util.List;
import java.util.Map;

/**
Expand All @@ -32,8 +31,4 @@ public interface FinancialServicesConfigurationService {

public Map<String, Map<Integer, String>> getAuthorizeSteps();

public Map<String, List<String>> getAllowedScopes();

public Map<String, List<String>> getAllowedAPIs();

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package org.wso2.financial.services.accelerator.common.config;

import java.util.List;
import java.util.Map;

/**
Expand All @@ -45,14 +44,4 @@ public Map<String, Map<Integer, String>> getAuthorizeSteps() {

return configParser.getConsentAuthorizeSteps();
}

@Override
public Map<String, List<String>> getAllowedScopes() {
return configParser.getAllowedScopes();
}

@Override
public Map<String, List<String>> getAllowedAPIs() {
return configParser.getAllowedAPIs();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class FinancialServicesConstants {
public static final String GATEWAY_CONFIG_TAG = "Gateway";
public static final String GATEWAY_EXECUTOR_CONFIG_TAG = "FinancialServicesGatewayExecutors";
public static final String EXECUTOR_CONFIG_TAG = "Executor";
public static final String DCR_CONFIG_TAG = "DCR";
public static final String COMMON_IDENTITY_CACHE_ACCESS_EXPIRY = "Common.Identity.Cache.CacheAccessExpiry";
public static final String COMMON_IDENTITY_CACHE_MODIFY_EXPIRY = "Common.Identity.Cache.CacheModifiedExpiry";
public static final String JWKS_CONNECTION_TIMEOUT = "JWKS-Retriever.ConnectionTimeout";
Expand All @@ -38,30 +37,17 @@ public class FinancialServicesConstants {
"DCR.RegistrationRequestParams.SoftwareEnvironmentIdentification.PropertyName";
public static final String DCR_SOFTWARE_ENV_IDENTIFICATION_VALUE_FOR_SANDBOX =
"DCR.RegistrationRequestParams.SoftwareEnvironmentIdentification.PropertyValueForSandbox";
public static final String REGULATORY_API_NAMES = "RegulatoryAPINames";
public static final String API_NAME = "name";
public static final String API_ROLE = "roles";
public static final String REGULATORY_API = "API";
public static final String JWT_HEAD = "head";
public static final String JWT_BODY = "body";
public static final String NEW_LINE = "[\r\n]";
public static final String JDBC_PERSISTENCE_CONFIG = "JDBCPersistenceManager.DataSource.Name";
public static final String DB_CONNECTION_VERIFICATION_TIMEOUT =
"JDBCPersistenceManager.ConnectionVerificationTimeout";
public static final String CONSENT_CONFIG_TAG = "Consent";
public static final String ALLOWED_SCOPES_CONFIG_TAG = "AllowedScopes";
public static final String SCOPE_CONFIG_TAG = "Scope";
public static final String TPP_MANAGEMENT_CONFIG_TAG = "TPPManagement";
public static final String CONNECTION_POOL_MAX_CONNECTIONS = "HTTPConnectionPool.MaxConnections";
public static final String CONNECTION_POOL_MAX_CONNECTIONS_PER_ROUTE = "HTTPConnectionPool.MaxConnectionsPerRoute";
public static final String IS_PSU_FEDERATED = "PSUFederatedAuthentication.Enabled";
public static final String PSU_FEDERATED_IDP_NAME = "PSUFederatedAuthentication.IDPName";

public static final String IDEMPOTENCY_IS_ENABLED = "Consent.Idempotency.Enabled";
public static final String IDEMPOTENCY_ALLOWED_TIME = "Consent.Idempotency.AllowedTimeDuration";
public static final String DOT_SEPARATOR = ".";
public static final String PRODUCTION = "PRODUCTION";
public static final String SANDBOX = "SANDBOX";

public static final String MANAGE_HANDLER = "Consent.ManageHandler";
public static final String AUTHORIZE_STEPS_CONFIG_TAG = "AuthorizeSteps";
public static final String STEP_CONFIG_TAG = "Step";
Expand All @@ -70,31 +56,37 @@ public class FinancialServicesConstants {
public static final String CONSENT_VALIDATOR = "Consent.Validation.Validator";
public static final String ADMIN_HANDLER = "Consent.AdminHandler";
public static final String PRESERVE_CONSENT = "Consent.PreserveConsentLink";
public static final String AUTH_SERVLET_EXTENSION = "Identity.AuthenticationWebApp.ServletExtension";
public static final String CONSENT_API_USERNAME = "Consent.ConsentAPICredentials.Username";
public static final String CONSENT_API_PASSWORD = "Consent.ConsentAPICredentials.Password";
public static final String MAX_INSTRUCTED_AMOUNT = "Consent.Payments.MaximumInstructedAmount";

public static final String AUTH_SERVLET_EXTENSION = "Identity.AuthenticationWebApp.ServletExtension";
public static final String REQUEST_VALIDATOR = "Identity.Extensions.RequestObjectValidator";
public static final String RESPONSE_HANDLER = "Identity.Extensions.ResponseTypeHandler";
public static final String CLAIM_PROVIDER = "Identity.Extensions.ClaimProvider";
public static final String CONSENT_ID_CLAIM_NAME = "Identity.ConsentIDClaimName";
public static final String MAX_INSTRUCTED_AMOUNT = "Consent.Payments.MaximumInstructedAmount";
public static final String REMOVE_USER_STORE_DOMAIN_FROM_SUBJECT =
"Identity.TokenSubject.RemoveUserStoreDomainFromSubject";
public static final String REMOVE_TENANT_DOMAIN_FROM_SUBJECT =
"Identity.TokenSubject.RemoveTenantDomainFromSubject";
public static final String KEYSTORE_LOCATION_TAG = "Security.InternalKeyStore.Location";
public static final String KEYSTORE_PASSWORD_TAG = "Security.InternalKeyStore.Password";
public static final String SIGNING_ALIAS_TAG = "Security.InternalKeyStore.KeyAlias";
public static final String SIGNING_KEY_PASSWORD = "Security.InternalKeyStore.KeyPassword";

public static final String PUBLISHER_HOSTNAME = "PublisherURL";
public static final String REQUEST_ROUTER = "Gateway.RequestRouter";
public static final String GATEWAY_CACHE_EXPIRY = "Gateway.Cache.GatewayCache.CacheAccessExpiry";
public static final String GATEWAY_CACHE_MODIFIED_EXPIRY = "Gateway.Cache.GatewayCache.CacheModifiedExpiry";
public static final String CONSENT_VALIDATION_ENDPOINT = "Gateway.ConsentValidationEndpoint";
public static final String KEYSTORE_LOCATION_TAG = "Security.InternalKeyStore.Location";
public static final String KEYSTORE_PASSWORD_TAG = "Security.InternalKeyStore.Password";
public static final String SIGNING_ALIAS_TAG = "Security.InternalKeyStore.KeyAlias";
public static final String SIGNING_KEY_PASSWORD = "Security.InternalKeyStore.KeyPassword";
public static final String VALIDATE_JWT = "Gateway.DCR.RequestJWTValidation";
public static final String JWKS_ENDPOINT_NAME = "Gateway.DCR.JWKSEndpointName";
public static final String SSA_CLIENT_NAME = "Gateway.DCR.SSAClientName";
public static final String DCR_USE_SOFTWAREID_AS_APPNAME = "Gateway.DCR.UseSoftwareIdAsAppName";

//Event Notifications Constants
public static final String EVENT_NOTIFICATION_GENERATOR = "EventNotifications.NotificationGeneration." +
"NotificationGenerator";
public static final String EVENT_NOTIFICATION_GENERATOR =
"EventNotifications.NotificationGeneration.NotificationGenerator";
public static final String TOKEN_ISSUER = "EventNotifications.NotificationGeneration.TokenIssuer";
public static final String MAX_SETS_TO_RETURN = "EventNotifications.NotificationGeneration.NumberOfSetsToReturn";
public static final String SIGNING_ALIAS = "EventNotifications.SigningAlias";
Expand All @@ -117,5 +109,11 @@ public class FinancialServicesConstants {
"EventNotifications.Realtime.EventNotificationThreadPoolSize";
public static final String REALTIME_EVENT_NOTIFICATION_REQUEST_GENERATOR =
"EventNotifications.Realtime.RequestGenerator";
}

public static final String JWT_HEAD = "head";
public static final String JWT_BODY = "body";
public static final String NEW_LINE = "[\r\n]";
public static final String DOT_SEPARATOR = ".";
public static final String PRODUCTION = "PRODUCTION";
public static final String SANDBOX = "SANDBOX";
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@

package org.wso2.financial.services.accelerator.common.util;

import com.nimbusds.jose.JWSObject;
import net.minidev.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
Expand Down Expand Up @@ -98,16 +97,16 @@ public static String getSoftwareEnvironmentFromSSA(String softwareStatement) thr
return FinancialServicesConstants.PRODUCTION;
}

final JSONObject softwareStatementBody = JWTUtils.decodeRequestJWT(softwareStatement,
FinancialServicesConstants.JWT_BODY);
String decodedSSA = JWTUtils.decodeRequestJWT(softwareStatement, FinancialServicesConstants.JWT_BODY);
final JSONObject softwareStatementBody = new JSONObject(decodedSSA);
// Retrieve the SSA property name used for software environment identification
final String sandboxEnvIdentificationPropertyName = FinancialServicesConfigParser.getInstance()
.getSoftwareEnvIdentificationSSAPropertyName();
// Retrieve the expected value for the sandbox environment
final String sandboxEnvIdentificationValue = FinancialServicesConfigParser.getInstance()
.getSoftwareEnvIdentificationSSAPropertyValueForSandbox();
return sandboxEnvIdentificationValue.equals(softwareStatementBody
.getAsString(sandboxEnvIdentificationPropertyName))
.getString(sandboxEnvIdentificationPropertyName))
? FinancialServicesConstants.SANDBOX
: FinancialServicesConstants.PRODUCTION;
}
Expand Down Expand Up @@ -147,24 +146,4 @@ public static boolean isRegulatoryApp(String clientId) throws RequestObjectExcep
"provider for clientId: " + clientId, e);
}
}

/**
* Decode request JWT.
*
* @param jwtToken jwt sent by the tpp
* @param jwtPart expected jwt part (header, body)
* @return json object containing requested jwt part
* @throws java.text.ParseException if an error occurs while parsing the jwt
*/
public static JSONObject decodeRequestJWT(String jwtToken, String jwtPart) throws java.text.ParseException {

JWSObject plainObject = JWSObject.parse(jwtToken);

if (FinancialServicesConstants.JWT_HEAD.equals(jwtPart)) {
return plainObject.getHeader().toJSONObject();
} else if (FinancialServicesConstants.JWT_BODY.equals(jwtPart)) {
return plainObject.getPayload().toJSONObject();
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
import net.minidev.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -91,19 +90,17 @@ public class JWTUtils {
* @return json object containing requested jwt part
* @throws ParseException if an error occurs while parsing the jwt
*/
public static JSONObject decodeRequestJWT(String jwtToken, String jwtPart) throws ParseException {

JSONObject jsonObject = new JSONObject();
public static String decodeRequestJWT(String jwtToken, String jwtPart) throws ParseException {

JWSObject plainObject = JWSObject.parse(jwtToken);

if ("head".equals(jwtPart)) {
jsonObject = plainObject.getHeader().toJSONObject();
} else if ("body".equals(jwtPart)) {
jsonObject = plainObject.getPayload().toJSONObject();
if (FinancialServicesConstants.JWT_HEAD.equals(jwtPart)) {
return plainObject.getHeader().toString();
} else if (FinancialServicesConstants.JWT_BODY.equals(jwtPart)) {
return plainObject.getPayload().toString();
}

return jsonObject;
return StringUtils.EMPTY;

}

Expand All @@ -121,7 +118,7 @@ public static JSONObject decodeRequestJWT(String jwtToken, String jwtPart) throw
* object
*/
@Generated(message = "Excluding from code coverage since can not call this method due to external https call")
public static boolean validateJWTSignature(String jwtString, String jwksUri, String algorithm)
public static JWTClaimsSet validateJWTSignature(String jwtString, String jwksUri, String algorithm)
throws ParseException, BadJOSEException, JOSEException, MalformedURLException {

int defaultConnectionTimeout = 3000;
Expand Down Expand Up @@ -155,8 +152,7 @@ public static boolean validateJWTSignature(String jwtString, String jwksUri, Str
jwtProcessor.setJWSKeySelector(keySelector);
// Process the token, set optional context parameters.
SimpleSecurityContext securityContext = new SimpleSecurityContext();
jwtProcessor.process((SignedJWT) jwt, securityContext);
return true;
return jwtProcessor.process((SignedJWT) jwt, securityContext);
}

/**
Expand Down
Loading
Loading