Skip to content

Commit

Permalink
#210 - Introduce ability to lock oxd to list of specific IDPs
Browse files Browse the repository at this point in the history
  • Loading branch information
duttarnab committed Sep 22, 2019
1 parent 64aff11 commit 3d553f0
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 10 deletions.
Expand Up @@ -50,6 +50,8 @@ public enum ErrorResponseCode {
INVALID_CLIENT_ID_REQUIRED(400, "invalid_client_id", "client_id is required parameter in request (skip client_secret if you wish to dynamically register client.)."),
UNSUPPORTED_OPERATION(500, "unsupported_operation", "Operation is not supported by server error."),
INVALID_OP_HOST(400, "invalid_op_host", "Invalid op_host (empty or blank)."),
INVALID_ALLOWED_OP_HOST_URL(400, "invalid_allowed_op_host_url", "Please check 1) The urls in allowed_op_hosts field of oxd-server.yml are valid. 2) If op_host url is valid."),
RESTRICTED_OP_HOST(400, "restricted_op_host", "oxd server is not allowed to access op_host. Please check if op_host url is present in allowed_op_hosts field of oxd-server.yml."),
BLANK_ACCESS_TOKEN(403, "blank_access_token", "access_token is blank. Command is protected by access_token, please provide valid token or otherwise switch off protection in configuration with protect_commands_with_access_token=false"),
INVALID_ACCESS_TOKEN(403, "invalid_access_token", "Invalid access_token. Command is protected by access_token, please provide valid token or otherwise switch off protection in configuration with protect_commands_with_access_token=false"),
NO_CLIENT_ID_IN_INTROSPECTION_RESPONSE(500, "invalid_introspection_response", "AS returned introspection response with empty/blank client_id which is required by oxd. Please check your AS installation and make sure AS return client_id for introspection call (CE 3.1.0 or later)."),
Expand Down
Expand Up @@ -3,8 +3,11 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Lists;
import io.dropwizard.Configuration;

import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class OxdServerConfiguration extends Configuration {

Expand Down Expand Up @@ -42,6 +45,8 @@ public class OxdServerConfiguration extends Configuration {
private Boolean addClientCredentialsGrantTypeAutomaticallyDuringClientRegistration = true;
@JsonProperty(value = "migration_source_folder_path")
private String migrationSourceFolderPath;
@JsonProperty(value = "allowed_op_hosts")
private List<String> allowedOpHosts = Lists.newArrayList();
@JsonProperty(value = "storage")
private String storage;
@JsonProperty(value = "storage_configuration")
Expand Down Expand Up @@ -208,6 +213,15 @@ public Boolean getAddClientCredentialsGrantTypeAutomaticallyDuringClientRegistra
public void setAddClientCredentialsGrantTypeAutomaticallyDuringClientRegistration(Boolean addClientCredentialsGrantTypeAutomaticallyDuringClientRegistration) {
this.addClientCredentialsGrantTypeAutomaticallyDuringClientRegistration = addClientCredentialsGrantTypeAutomaticallyDuringClientRegistration;
}

public List<String> getAllowedOpHosts() {
return allowedOpHosts;
}

public void setAllowedOpHosts(List<String> allowedOpHosts) {
this.allowedOpHosts = allowedOpHosts;
}

@Override
public String toString() {
return "OxdServerConfiguration{" +
Expand All @@ -228,8 +242,9 @@ public String toString() {
", uma2AuthRegisterClaimsGatheringEndpointAsRedirectUriOfClient=" + uma2AuthRegisterClaimsGatheringEndpointAsRedirectUriOfClient +
", migrationSourceFolderPath='" + migrationSourceFolderPath + '\'' +
", storage='" + storage + '\'' +
", storageConfiguration=" + storageConfiguration +
", defaultSiteConfig=" + defaultSiteConfig +
", storageConfiguration=" + storageConfiguration + '\'' +
", defaultSiteConfig=" + defaultSiteConfig + '\'' +
", allowedOpHosts=" + allowedOpHosts + '\'' +
", addClientCredentialsGrantTypeAutomaticallyDuringClientRegistration=" + addClientCredentialsGrantTypeAutomaticallyDuringClientRegistration +
'}';
}
Expand Down
Expand Up @@ -227,6 +227,8 @@ private void persistRp(String siteId, RegisterSiteParams params) {
}

getRpService().create(rp);
} catch (HttpException e) {
throw e;
} catch (Exception e) {
LOG.error("Failed to persist site configuration, params: " + params, e);
throw new RuntimeException(e);
Expand Down
Expand Up @@ -5,15 +5,14 @@

import com.google.inject.Inject;
import org.apache.commons.lang.StringUtils;
import org.gluu.oxd.server.op.OpClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.gluu.oxauth.client.OpenIdConfigurationClient;
import org.gluu.oxauth.client.OpenIdConfigurationResponse;
import org.gluu.oxauth.client.uma.UmaClientFactory;
import org.gluu.oxauth.model.uma.UmaMetadata;
import org.gluu.oxd.common.ErrorResponseCode;
import org.gluu.oxd.server.HttpException;
import org.gluu.oxd.server.op.OpClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLHandshakeException;
import javax.ws.rs.WebApplicationException;
Expand Down Expand Up @@ -66,6 +65,7 @@ public OpenIdConfigurationResponse getConnectDiscoveryResponse(Rp rp) {

public OpenIdConfigurationResponse getConnectDiscoveryResponse(String opHost, String opDiscoveryPath) {
validationService.notBlankOpHost(opHost);
validationService.isOpHostAllowed(opHost);

try {
final OpenIdConfigurationResponse r = map.get(opHost);
Expand Down Expand Up @@ -104,6 +104,7 @@ public UmaMetadata getUmaDiscoveryByOxdId(String oxdId) {

public UmaMetadata getUmaDiscovery(String opHost, String opDiscoveryPath) {
validationService.notBlankOpHost(opHost);
validationService.isOpHostAllowed(opHost);

try {
final UmaMetadata r = umaMap.get(opHost);
Expand Down
Expand Up @@ -2,15 +2,19 @@

import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.gluu.oxauth.model.common.IntrospectionResponse;
import org.gluu.oxd.common.ErrorResponseCode;
import org.gluu.oxd.common.params.*;
import org.gluu.oxd.server.HttpException;
import org.gluu.oxd.server.OxdServerConfiguration;
import org.gluu.oxd.server.ServerLauncher;
import org.gluu.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

/**
* @author Yuriy Zabrovarnyy
Expand All @@ -19,6 +23,7 @@
public class ValidationService {

private static final Logger LOG = LoggerFactory.getLogger(ValidationService.class);
final OxdServerConfiguration configuration = ServerLauncher.getInjector().getInstance(ConfigurationService.class).get();

private void notNull(IParams params) {
if (params == null) {
Expand All @@ -38,6 +43,23 @@ public void notBlankOpHost(String opHost) {
}
}

public void isOpHostAllowed(String opHost) {
List<String> allowedOpHosts = configuration.getAllowedOpHosts();
if (!Strings.isNullOrEmpty(opHost) && !allowedOpHosts.isEmpty()) {
if (!allowedOpHosts.stream().anyMatch(allowedUrl ->
{
try {
return (new URL(allowedUrl)).equals(new URL(opHost));
} catch (MalformedURLException e) {
throw new HttpException(ErrorResponseCode.INVALID_ALLOWED_OP_HOST_URL);
}
}
)) {
throw new HttpException(ErrorResponseCode.RESTRICTED_OP_HOST);
}
}
}

public Pair<Rp, Boolean> validate(IParams params) {
notNull(params);
if (isInstanceOfGetRpParamsWithList(params)) {
Expand Down Expand Up @@ -97,7 +119,6 @@ public Pair<Rp, Boolean> validate(IParams params) {
* @return true - client is remote, false - client is local. If validation does not pass exception must be thrown
*/
private boolean validate(HasAccessTokenParams params) {
final OxdServerConfiguration configuration = ServerLauncher.getInjector().getInstance(ConfigurationService.class).get();
if (configuration.getProtectCommandsWithAccessToken() != null && !configuration.getProtectCommandsWithAccessToken()) {
return false; // skip validation since protectCommandsWithAccessToken=false
}
Expand Down Expand Up @@ -163,6 +184,7 @@ public Rp validate(Rp rp) {

notBlankOxdId(rp.getOxdId());
notBlankOpHost(rp.getOpHost());
isOpHostAllowed(rp.getOpHost());
return rp;
}

Expand All @@ -173,4 +195,5 @@ private static boolean isInstanceOfGetRpParamsWithList(IParams params) {
}
return false;
}
}
}

1 change: 1 addition & 0 deletions oxd-server/src/main/resources/oxd-server.yml
Expand Up @@ -15,6 +15,7 @@ protect_commands_with_access_token: true
uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client: false
add_client_credentials_grant_type_automatically_during_client_registration: true
migration_source_folder_path: ''
allowed_op_hosts: []
storage: h2
storage_configuration:
dbFileLocation: /opt/oxd-server/data/oxd_db
Expand Down
1 change: 1 addition & 0 deletions oxd-server/src/test/resources/oxd-conf-test-h2-conf.json
Expand Up @@ -14,6 +14,7 @@
"protect_commands_with_access_token": false,
"uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client":true,
"migration_source_folder_path":"",
"allowed_op_hosts": [],
"storage":"h2",
"storage_configuration": {
"dbFileLocation":"u:\\opt\\oxd-server\\bin\\oxd_db"
Expand Down
1 change: 1 addition & 0 deletions oxd-server/src/test/resources/oxd-conf-test-redis.json
Expand Up @@ -14,6 +14,7 @@
"protect_commands_with_access_token": false,
"uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client":true,
"migration_source_folder_path":"",
"allowed_op_hosts": [],
"storage":"redis",
"storage_configuration": {
"servers":"localhost:6379",
Expand Down
1 change: 1 addition & 0 deletions oxd-server/src/test/resources/oxd-conf-test.json
Expand Up @@ -18,6 +18,7 @@
"uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client":true,
"add_client_credentials_grant_type_automatically_during_client_registration":true,
"migration_source_folder_path":"",
"allowed_op_hosts": [],
"storage":"h2",
"storage_configuration": {
"dbFileLocation":"./oxd_db"
Expand Down
1 change: 1 addition & 0 deletions oxd-server/src/test/resources/oxd-server-dev.yml
Expand Up @@ -15,6 +15,7 @@ protect_commands_with_access_token: false
uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client: true
add_client_credentials_grant_type_automatically_during_client_registration: true
migration_source_folder_path: ''
allowed_op_hosts: []
storage: h2
storage_configuration:
dbFileLocation: "./oxd_db"
Expand Down
1 change: 1 addition & 0 deletions oxd-server/src/test/resources/oxd-server-jenkins.yml
Expand Up @@ -15,6 +15,7 @@ protect_commands_with_access_token: false
uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client: true
add_client_credentials_grant_type_automatically_during_client_registration: true
migration_source_folder_path: ''
allowed_op_hosts: []
storage: h2
storage_configuration:
dbFileLocation: "./oxd_db"
Expand Down
1 change: 1 addition & 0 deletions upgrade/oxd-server.yml.temp
Expand Up @@ -14,6 +14,7 @@ protect_commands_with_access_token: {{protect_commands_with_access_token}}
uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client: {{uma2_auto_register_claims_gathering_endpoint_as_redirect_uri_of_client}}
add_client_credentials_grant_type_automatically_during_client_registration: {{add_client_credentials_grant_type_automatically_during_client_registration}}
migration_source_folder_path: {{migration_source_folder_path}}
allowed_op_hosts: {{allowed_op_hosts}}
storage: h2
storage_configuration:
dbFileLocation: {{storage_configuration:dbFileLocation}}
Expand Down

0 comments on commit 3d553f0

Please sign in to comment.