- Formalized the notion of a client vs. node mode. Introduced an `AbstractShieldModule` that takes care of that
- For now, standarized on the `Shield` name across the board (e.g. change `SecurityModule` to `ShieldModule`)
- Introduces static methods to `ShieldPlugin` to resolve shield specific config files (on the way fixed the file resolving of the ldap group mapper)
- The n2n ip filtering is now resolved at the module level. If not enabled, null is injected and the netty handler is then not injected to the pipeline
- updated code base with the latest changes in es-core around how relevant http headers are registered and copied over to the transport request
- Added new known action in es-core  `indices:admin/get`

Original commit: elastic/x-pack-elasticsearch@ca8d85dc81
This commit is contained in:
uboness 2014-09-10 14:23:50 +03:00
parent 787a415c27
commit 1588c761ea
39 changed files with 369 additions and 201 deletions

View File

@ -5,15 +5,20 @@
*/ */
package org.elasticsearch.shield; package org.elasticsearch.shield;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.support.AbstractShieldModule;
/** /**
* *
*/ */
public class SecurityFilterModule extends AbstractModule { public class SecurityFilterModule extends AbstractShieldModule.Node {
public SecurityFilterModule(Settings settings) {
super(settings);
}
@Override @Override
protected void configure() { protected void configureNode() {
bind(SecurityFilter.class).asEagerSingleton(); bind(SecurityFilter.class).asEagerSingleton();
} }
} }

View File

@ -9,24 +9,24 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.collect.Lists;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import java.util.List; import java.util.List;
/** /**
* *
*/ */
public class SecurityException extends ElasticsearchException.WithRestHeaders { public class ShieldException extends ElasticsearchException.WithRestHeaders {
public static final ImmutableMap<String, List<String>> HEADERS = ImmutableMap.<String, List<String>>builder() public static final ImmutableMap<String, List<String>> HEADERS = ImmutableMap.<String, List<String>>builder()
.put("WWW-Authenticate", Lists.newArrayList("Basic realm=\""+ SecurityPlugin.NAME +"\"")) .put("WWW-Authenticate", Lists.newArrayList("Basic realm=\""+ ShieldPlugin.NAME +"\""))
.build(); .build();
public SecurityException(String msg) { public ShieldException(String msg) {
super(msg, HEADERS); super(msg, HEADERS);
} }
public SecurityException(String msg, Throwable cause) { public ShieldException(String msg, Throwable cause) {
super(msg, cause, HEADERS); super(msg, cause, HEADERS);
} }
} }

View File

@ -7,61 +7,60 @@ package org.elasticsearch.shield;
import org.elasticsearch.action.ActionModule; import org.elasticsearch.action.ActionModule;
import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule; import org.elasticsearch.common.inject.PreProcessModule;
import org.elasticsearch.common.inject.SpawnModules;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.audit.AuditTrailModule; import org.elasticsearch.shield.audit.AuditTrailModule;
import org.elasticsearch.shield.authc.AuthenticationModule; import org.elasticsearch.shield.authc.AuthenticationModule;
import org.elasticsearch.shield.authz.AuthorizationModule; import org.elasticsearch.shield.authz.AuthorizationModule;
import org.elasticsearch.shield.support.AbstractShieldModule;
import org.elasticsearch.shield.transport.SecuredRestModule; import org.elasticsearch.shield.transport.SecuredRestModule;
import org.elasticsearch.shield.transport.SecuredTransportModule; import org.elasticsearch.shield.transport.SecuredTransportModule;
/** /**
* *
*/ */
public class SecurityModule extends AbstractModule implements SpawnModules, PreProcessModule { public class ShieldModule extends AbstractShieldModule.Spawn implements PreProcessModule {
private final Settings settings; private final boolean enabled;
private final boolean isClient;
private final boolean isShieldEnabled;
public SecurityModule(Settings settings) { public ShieldModule(Settings settings) {
this.settings = settings; super(settings);
this.isClient = settings.getAsBoolean("node.client", false); this.enabled = settings.getAsBoolean("shield.enabled", true);
this.isShieldEnabled = settings.getAsBoolean("shield.enabled", true);
} }
@Override @Override
public void processModule(Module module) { public void processModule(Module module) {
if (module instanceof ActionModule && isShieldEnabled && !isClient) { if (module instanceof ActionModule && enabled && !clientMode) {
((ActionModule) module).registerFilter(SecurityFilter.Action.class); ((ActionModule) module).registerFilter(SecurityFilter.Action.class);
} }
} }
@Override @Override
public Iterable<? extends Module> spawnModules() { public Iterable<? extends Module> spawnModules(boolean clientMode) {
// don't spawn modules if shield is explicitly disabled // don't spawn modules if shield is explicitly disabled
if (!isShieldEnabled) { if (!enabled) {
return ImmutableList.of(); return ImmutableList.of();
} }
// spawn needed parts in client mode // spawn needed parts in client mode
if (isClient) { if (clientMode) {
return ImmutableList.of(new SecuredTransportModule(), new SecurityFilterModule()); return ImmutableList.of(
new SecuredTransportModule(settings),
new SecurityFilterModule(settings));
} }
return ImmutableList.of( return ImmutableList.of(
new AuthenticationModule(settings), new AuthenticationModule(settings),
new AuthorizationModule(), new AuthorizationModule(settings),
new AuditTrailModule(settings), new AuditTrailModule(settings),
new SecuredTransportModule(), new SecuredTransportModule(settings),
new SecuredRestModule(), new SecuredRestModule(settings),
new SecurityFilterModule()); new SecurityFilterModule(settings));
} }
@Override @Override
protected void configure() { protected void configure(boolean clientMode) {
} }
} }

View File

@ -8,13 +8,13 @@ package org.elasticsearch.shield;
/** /**
* *
*/ */
public class SecuritySettingsException extends SecurityException { public class ShieldSettingsException extends ShieldException {
public SecuritySettingsException(String msg) { public ShieldSettingsException(String msg) {
super(msg); super(msg);
} }
public SecuritySettingsException(String msg, Throwable cause) { public ShieldSettingsException(String msg, Throwable cause) {
super(msg, cause); super(msg, cause);
} }

View File

@ -5,10 +5,12 @@
*/ */
package org.elasticsearch.shield.audit; package org.elasticsearch.shield.audit;
import org.elasticsearch.shield.ShieldException;
/** /**
* *
*/ */
public class AuditException extends org.elasticsearch.shield.SecurityException { public class AuditException extends ShieldException {
public AuditException(String msg) { public AuditException(String msg) {
super(msg); super(msg);

View File

@ -7,27 +7,28 @@ package org.elasticsearch.shield.audit;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.collect.Sets; import org.elasticsearch.common.collect.Sets;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.multibindings.Multibinder; import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail; import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
import org.elasticsearch.shield.support.AbstractShieldModule;
import java.util.Set; import java.util.Set;
/** /**
* *
*/ */
public class AuditTrailModule extends AbstractModule { public class AuditTrailModule extends AbstractShieldModule.Node {
private final Settings settings; private final boolean enabled;
public AuditTrailModule(Settings settings) { public AuditTrailModule(Settings settings) {
this.settings = settings; super(settings);
enabled = settings.getAsBoolean("shield.audit.enabled", false);
} }
@Override @Override
protected void configure() { protected void configureNode() {
if (!settings.getAsBoolean("shield.audit.enabled", false)) { if (!enabled) {
bind(AuditTrail.class).toInstance(AuditTrail.NOOP); bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
return; return;
} }

View File

@ -6,11 +6,12 @@
package org.elasticsearch.shield.authc; package org.elasticsearch.shield.authc;
import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.ShieldException;
/** /**
* *
*/ */
public class AuthenticationException extends org.elasticsearch.shield.SecurityException { public class AuthenticationException extends ShieldException {
public AuthenticationException(String msg) { public AuthenticationException(String msg) {
super(msg); super(msg);

View File

@ -6,55 +6,31 @@
package org.elasticsearch.shield.authc; package org.elasticsearch.shield.authc;
import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.SpawnModules;
import org.elasticsearch.common.inject.util.Providers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.authc.esusers.ESUsersModule; import org.elasticsearch.shield.authc.esusers.ESUsersModule;
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
import org.elasticsearch.shield.authc.ldap.LdapModule; import org.elasticsearch.shield.authc.ldap.LdapModule;
import org.elasticsearch.shield.authc.ldap.LdapRealm;
import org.elasticsearch.shield.authc.system.SystemRealm; import org.elasticsearch.shield.authc.system.SystemRealm;
import org.elasticsearch.shield.support.AbstractShieldModule;
import static org.elasticsearch.common.inject.name.Names.named;
/** /**
* *
*/ */
public class AuthenticationModule extends AbstractModule implements SpawnModules { public class AuthenticationModule extends AbstractShieldModule.Node.Spawn {
private final Settings settings;
private final boolean esusersEnabled;
private final boolean ldapEnabled;
public AuthenticationModule(Settings settings) { public AuthenticationModule(Settings settings) {
this.settings = settings; super(settings);
this.esusersEnabled = ESUsersModule.enabled(settings);
this.ldapEnabled = LdapModule.enabled(settings);
} }
@Override @Override
public Iterable<? extends Module> spawnModules() { public Iterable<? extends Node> spawnModules() {
ImmutableList.Builder<Module> modules = ImmutableList.builder(); return ImmutableList.of(
modules.add(new SystemRealm.Module()); new SystemRealm.Module(settings),
if (esusersEnabled) { new ESUsersModule(settings),
modules.add(new ESUsersModule()); new LdapModule(settings));
}
if (ldapEnabled) {
modules.add(new LdapModule(settings));
}
return modules.build();
} }
@Override @Override
protected void configure() { protected void configureNode() {
bind(AuthenticationService.class).to(InternalAuthenticationService.class).asEagerSingleton(); bind(AuthenticationService.class).to(InternalAuthenticationService.class).asEagerSingleton();
if (!esusersEnabled) {
bind(ESUsersRealm.class).toProvider(Providers.of((ESUsersRealm) null));
}
if (!ldapEnabled) {
bind(LdapRealm.class).toProvider(Providers.of((LdapRealm) null));
}
} }
} }

View File

@ -5,27 +5,39 @@
*/ */
package org.elasticsearch.shield.authc.esusers; package org.elasticsearch.shield.authc.esusers;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.util.Providers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.authc.Realm; import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.authc.support.UserPasswdStore; import org.elasticsearch.shield.authc.support.UserPasswdStore;
import org.elasticsearch.shield.authc.support.UserRolesStore; import org.elasticsearch.shield.authc.support.UserRolesStore;
import org.elasticsearch.shield.support.AbstractShieldModule;
import static org.elasticsearch.common.inject.name.Names.named; import static org.elasticsearch.common.inject.name.Names.named;
/** /**
* *
*/ */
public class ESUsersModule extends AbstractModule { public class ESUsersModule extends AbstractShieldModule.Node {
public static boolean enabled(Settings settings) { private final boolean enabled;
return settings.getComponentSettings(ESUsersModule.class).getAsBoolean("enabled", true);
public ESUsersModule(Settings settings) {
super(settings);
enabled = enabled(settings);
} }
@Override @Override
protected void configure() { protected void configureNode() {
bind(Realm.class).annotatedWith(named(ESUsersRealm.TYPE)).to(ESUsersRealm.class).asEagerSingleton(); if (enabled) {
bind(UserPasswdStore.class).annotatedWith(named("file")).to(FileUserPasswdStore.class).asEagerSingleton(); bind(Realm.class).annotatedWith(named(ESUsersRealm.TYPE)).to(ESUsersRealm.class).asEagerSingleton();
bind(UserRolesStore.class).annotatedWith(named("file")).to(FileUserRolesStore.class).asEagerSingleton(); bind(UserPasswdStore.class).annotatedWith(named("file")).to(FileUserPasswdStore.class).asEagerSingleton();
bind(UserRolesStore.class).annotatedWith(named("file")).to(FileUserRolesStore.class).asEagerSingleton();
} else {
bind(ESUsersRealm.class).toProvider(Providers.<ESUsersRealm>of(null));
}
}
static boolean enabled(Settings settings) {
return settings.getComponentSettings(ESUsersModule.class).getAsBoolean("enabled", true);
} }
} }

View File

@ -10,7 +10,7 @@ import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.name.Named; import org.elasticsearch.common.inject.name.Named;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.AuthenticationToken; import org.elasticsearch.shield.authc.AuthenticationToken;
@ -25,20 +25,18 @@ import org.elasticsearch.transport.TransportMessage;
*/ */
public class ESUsersRealm extends AbstractComponent implements Realm<UsernamePasswordToken> { public class ESUsersRealm extends AbstractComponent implements Realm<UsernamePasswordToken> {
static {
BaseRestHandler.addUsefulHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
}
public static final String TYPE = "esusers"; public static final String TYPE = "esusers";
final UserPasswdStore userPasswdStore; final UserPasswdStore userPasswdStore;
final UserRolesStore userRolesStore; final UserRolesStore userRolesStore;
@Inject @Inject
public ESUsersRealm(Settings settings, @Named("file") UserPasswdStore userPasswdStore, @Named("file") UserRolesStore userRolesStore) { public ESUsersRealm(Settings settings, @Named("file") UserPasswdStore userPasswdStore,
@Named("file") UserRolesStore userRolesStore, RestController restController) {
super(settings); super(settings);
this.userPasswdStore = userPasswdStore; this.userPasswdStore = userPasswdStore;
this.userRolesStore = userRolesStore; this.userRolesStore = userRolesStore;
restController.registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
} }
@Override @Override

View File

@ -16,7 +16,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.authc.support.Hasher; import org.elasticsearch.shield.authc.support.Hasher;
import org.elasticsearch.shield.authc.support.UserPasswdStore; import org.elasticsearch.shield.authc.support.UserPasswdStore;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileChangesListener;
import org.elasticsearch.watcher.FileWatcher; import org.elasticsearch.watcher.FileWatcher;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
@ -75,8 +75,7 @@ public class FileUserPasswdStore extends AbstractComponent implements UserPasswd
public static Path resolveFile(Settings settings, Environment env) { public static Path resolveFile(Settings settings, Environment env) {
String location = settings.get("shield.authc.esusers.files.users"); String location = settings.get("shield.authc.esusers.files.users");
if (location == null) { if (location == null) {
File shieldDirectory = new File(env.configFile(), SecurityPlugin.NAME); return ShieldPlugin.resolveConfigFile(env, ".users");
return shieldDirectory.toPath().resolve(".users");
} }
return Paths.get(location); return Paths.get(location);
} }

View File

@ -16,7 +16,7 @@ import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.authc.support.UserRolesStore; import org.elasticsearch.shield.authc.support.UserRolesStore;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileChangesListener;
import org.elasticsearch.watcher.FileWatcher; import org.elasticsearch.watcher.FileWatcher;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
@ -68,8 +68,7 @@ public class FileUserRolesStore extends AbstractComponent implements UserRolesSt
public static Path resolveFile(Settings settings, Environment env) { public static Path resolveFile(Settings settings, Environment env) {
String location = settings.get("shield.authc.esusers.files.users_roles"); String location = settings.get("shield.authc.esusers.files.users_roles");
if (location == null) { if (location == null) {
File shieldDirectory = new File(env.configFile(), SecurityPlugin.NAME); return ShieldPlugin.resolveConfigFile(env, ".users_roles");
return shieldDirectory.toPath().resolve(".users_roles");
} }
return Paths.get(location); return Paths.get(location);
} }

View File

@ -10,6 +10,7 @@ import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.ShieldException;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.NamingEnumeration; import javax.naming.NamingEnumeration;
@ -42,7 +43,7 @@ public class ActiveDirectoryConnectionFactory extends AbstractComponent implemen
super(settings); super(settings);
domainName = componentSettings.get(AD_DOMAIN_NAME_SETTING); domainName = componentSettings.get(AD_DOMAIN_NAME_SETTING);
if (domainName == null) { if (domainName == null) {
throw new org.elasticsearch.shield.SecurityException("Missing [" + AD_DOMAIN_NAME_SETTING + "] setting for active directory"); throw new ShieldException("Missing [" + AD_DOMAIN_NAME_SETTING + "] setting for active directory");
} }
userSearchDN = componentSettings.get(AD_USER_SEARCH_BASEDN_SETTING, buildDnFromDomain(domainName)); userSearchDN = componentSettings.get(AD_USER_SEARCH_BASEDN_SETTING, buildDnFromDomain(domainName));
int port = componentSettings.getAsInt(AD_PORT, 389); int port = componentSettings.getAsInt(AD_PORT, 389);

View File

@ -13,6 +13,7 @@ import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileChangesListener;
import org.elasticsearch.watcher.FileWatcher; import org.elasticsearch.watcher.FileWatcher;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
@ -32,7 +33,7 @@ import java.util.*;
*/ */
public class LdapGroupToRoleMapper extends AbstractComponent { public class LdapGroupToRoleMapper extends AbstractComponent {
public static final String ROLE_MAPPING_DEFAULT_FILE_NAME = ".role_mapping"; public static final String DEFAULT_FILE_NAME = ".role_mapping";
public static final String ROLE_MAPPING_FILE_SETTING = "files.role_mapping"; public static final String ROLE_MAPPING_FILE_SETTING = "files.role_mapping";
public static final String USE_UNMAPPED_GROUPS_AS_ROLES_SETTING = "unmapped_groups_as_roles"; public static final String USE_UNMAPPED_GROUPS_AS_ROLES_SETTING = "unmapped_groups_as_roles";
@ -57,6 +58,14 @@ public class LdapGroupToRoleMapper extends AbstractComponent {
this.listener = listener; this.listener = listener;
} }
public static Path resolveFile(Settings settings, Environment env) {
String location = settings.get(ROLE_MAPPING_FILE_SETTING);
if (location == null) {
return ShieldPlugin.resolveConfigFile(env, DEFAULT_FILE_NAME);
}
return Paths.get(location);
}
public static ImmutableMap<LdapName, Set<String>> parseFile(Path path, ESLogger logger) { public static ImmutableMap<LdapName, Set<String>> parseFile(Path path, ESLogger logger) {
if (!Files.exists(path)) { if (!Files.exists(path)) {
return ImmutableMap.of(); return ImmutableMap.of();
@ -92,14 +101,6 @@ public class LdapGroupToRoleMapper extends AbstractComponent {
} }
} }
public static Path resolveFile(Settings settings, Environment env) {
String location = settings.get(ROLE_MAPPING_FILE_SETTING);
if (location == null) {
return env.configFile().toPath().resolve(ROLE_MAPPING_DEFAULT_FILE_NAME);
}
return Paths.get(location);
}
/** /**
* This will map the groupDN's to ES Roles * This will map the groupDN's to ES Roles
*/ */

View File

@ -5,24 +5,42 @@
*/ */
package org.elasticsearch.shield.authc.ldap; package org.elasticsearch.shield.authc.ldap;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.util.Providers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.authc.AuthenticationModule;
import org.elasticsearch.shield.authc.Realm; import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.support.AbstractShieldModule;
import static org.elasticsearch.common.inject.name.Names.named; import static org.elasticsearch.common.inject.name.Names.named;
/** /**
* Configures Ldap object injections * Configures Ldap object injections
*/ */
public class LdapModule extends AbstractModule { public class LdapModule extends AbstractShieldModule.Node {
private final Settings settings;
private final boolean enabled;
public LdapModule(Settings settings) { public LdapModule(Settings settings) {
this.settings = settings; super(settings);
enabled = enabled(settings);
} }
public static boolean enabled(Settings settings) { @Override
protected void configureNode() {
if (enabled) {
bind(Realm.class).annotatedWith(named(LdapRealm.TYPE)).to(LdapRealm.class).asEagerSingleton();
bind(LdapGroupToRoleMapper.class).asEagerSingleton();
String mode = settings.getComponentSettings(LdapModule.class).get("mode", "ldap");
if ("ldap".equals(mode)) {
bind(LdapConnectionFactory.class).to(StandardLdapConnectionFactory.class);
} else {
bind(LdapConnectionFactory.class).to(ActiveDirectoryConnectionFactory.class);
}
} else {
bind(LdapRealm.class).toProvider(Providers.of((LdapRealm) null));
}
}
static boolean enabled(Settings settings) {
Settings authcSettings = settings.getAsSettings("shield.authc"); Settings authcSettings = settings.getAsSettings("shield.authc");
if (!authcSettings.names().contains("ldap")) { if (!authcSettings.names().contains("ldap")) {
return false; return false;
@ -30,16 +48,4 @@ public class LdapModule extends AbstractModule {
Settings ldapSettings = authcSettings.getAsSettings("ldap"); Settings ldapSettings = authcSettings.getAsSettings("ldap");
return ldapSettings.getAsBoolean("enabled", true); return ldapSettings.getAsBoolean("enabled", true);
} }
@Override
protected void configure() {
bind(Realm.class).annotatedWith(named(LdapRealm.TYPE)).to(LdapRealm.class).asEagerSingleton();
bind(LdapGroupToRoleMapper.class).asEagerSingleton();
String mode = settings.getComponentSettings(LdapModule.class).get("mode", "ldap");
if ("ldap".equals(mode)) {
bind(LdapConnectionFactory.class).to(StandardLdapConnectionFactory.class);
} else {
bind(LdapConnectionFactory.class).to(ActiveDirectoryConnectionFactory.class);
}
}
} }

View File

@ -7,10 +7,10 @@ package org.elasticsearch.shield.authc.ldap;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.ShieldException;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.AuthenticationToken; import org.elasticsearch.shield.authc.AuthenticationToken;
import org.elasticsearch.shield.SecurityException;
import org.elasticsearch.shield.authc.Realm; import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.authc.support.CachingUsernamePasswordRealm; import org.elasticsearch.shield.authc.support.CachingUsernamePasswordRealm;
import org.elasticsearch.shield.authc.support.UsernamePasswordToken; import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
@ -25,21 +25,17 @@ import java.util.Set;
*/ */
public class LdapRealm extends CachingUsernamePasswordRealm implements Realm<UsernamePasswordToken> { public class LdapRealm extends CachingUsernamePasswordRealm implements Realm<UsernamePasswordToken> {
static {
BaseRestHandler.addUsefulHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
}
public static final String TYPE = "ldap"; public static final String TYPE = "ldap";
private final LdapConnectionFactory connectionFactory; private final LdapConnectionFactory connectionFactory;
private final LdapGroupToRoleMapper roleMapper; private final LdapGroupToRoleMapper roleMapper;
@Inject @Inject
public LdapRealm(Settings settings, LdapConnectionFactory ldap, LdapGroupToRoleMapper roleMapper) { public LdapRealm(Settings settings, LdapConnectionFactory ldap, LdapGroupToRoleMapper roleMapper, RestController restController) {
super(settings); super(settings);
this.connectionFactory = ldap; this.connectionFactory = ldap;
this.roleMapper = roleMapper; this.roleMapper = roleMapper;
restController.registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
} }
@Override @Override
@ -68,7 +64,7 @@ public class LdapRealm extends CachingUsernamePasswordRealm implements Realm<Use
User.Simple user = new User.Simple(token.principal(), roles.toArray(new String[roles.size()])); User.Simple user = new User.Simple(token.principal(), roles.toArray(new String[roles.size()]));
Arrays.fill(token.credentials(), '\0'); Arrays.fill(token.credentials(), '\0');
return user; return user;
} catch (SecurityException e){ } catch (ShieldException e){
logger.info("Authentication Failed for user [{}]", e, token.principal()); logger.info("Authentication Failed for user [{}]", e, token.principal());
return null; return null;
} }

View File

@ -10,6 +10,7 @@ import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.ShieldException;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.NamingException; import javax.naming.NamingException;
@ -43,11 +44,11 @@ public class StandardLdapConnectionFactory extends AbstractComponent implements
super(settings); super(settings);
userDnTemplates = componentSettings.getAsArray(USER_DN_TEMPLATES_SETTING); userDnTemplates = componentSettings.getAsArray(USER_DN_TEMPLATES_SETTING);
if (userDnTemplates == null) { if (userDnTemplates == null) {
throw new org.elasticsearch.shield.SecurityException("Missing required ldap setting [" + USER_DN_TEMPLATES_SETTING + "]"); throw new ShieldException("Missing required ldap setting [" + USER_DN_TEMPLATES_SETTING + "]");
} }
String[] ldapUrls = componentSettings.getAsArray(URLS_SETTING); String[] ldapUrls = componentSettings.getAsArray(URLS_SETTING);
if (ldapUrls == null) { if (ldapUrls == null) {
throw new org.elasticsearch.shield.SecurityException("Missing required ldap setting [" + URLS_SETTING + "]"); throw new ShieldException("Missing required ldap setting [" + URLS_SETTING + "]");
} }
sharedLdapEnv = ImmutableMap.<String, Serializable>builder() sharedLdapEnv = ImmutableMap.<String, Serializable>builder()
.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory") .put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory")

View File

@ -5,11 +5,12 @@
*/ */
package org.elasticsearch.shield.authc.system; package org.elasticsearch.shield.authc.system;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.AuthenticationToken; import org.elasticsearch.shield.authc.AuthenticationToken;
import org.elasticsearch.shield.authc.Realm; import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.support.AbstractShieldModule;
import org.elasticsearch.transport.TransportMessage; import org.elasticsearch.transport.TransportMessage;
/** /**
@ -58,9 +59,14 @@ public class SystemRealm implements Realm<AuthenticationToken> {
return token == TOKEN ? User.SYSTEM : null; return token == TOKEN ? User.SYSTEM : null;
} }
public static class Module extends AbstractModule { public static class Module extends AbstractShieldModule.Node {
public Module(Settings settings) {
super(settings);
}
@Override @Override
protected void configure() { protected void configureNode() {
bind(SystemRealm.class).asEagerSingleton(); bind(SystemRealm.class).asEagerSingleton();
} }
} }

View File

@ -6,11 +6,12 @@
package org.elasticsearch.shield.authz; package org.elasticsearch.shield.authz;
import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.ShieldException;
/** /**
* *
*/ */
public class AuthorizationException extends org.elasticsearch.shield.SecurityException { public class AuthorizationException extends ShieldException {
public AuthorizationException(String msg) { public AuthorizationException(String msg) {
super(msg); super(msg);

View File

@ -5,17 +5,22 @@
*/ */
package org.elasticsearch.shield.authz; package org.elasticsearch.shield.authz;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.authz.store.FileRolesStore; import org.elasticsearch.shield.authz.store.FileRolesStore;
import org.elasticsearch.shield.authz.store.RolesStore; import org.elasticsearch.shield.authz.store.RolesStore;
import org.elasticsearch.shield.support.AbstractShieldModule;
/** /**
* *
*/ */
public class AuthorizationModule extends AbstractModule { public class AuthorizationModule extends AbstractShieldModule.Node {
public AuthorizationModule(Settings settings) {
super(settings);
}
@Override @Override
protected void configure() { protected void configureNode() {
bind(RolesStore.class).to(FileRolesStore.class); bind(RolesStore.class).to(FileRolesStore.class);
bind(AuthorizationService.class).to(InternalAuthorizationService.class).asEagerSingleton(); bind(AuthorizationService.class).to(InternalAuthorizationService.class).asEagerSingleton();
} }

View File

@ -21,7 +21,7 @@ import org.elasticsearch.common.xcontent.yaml.YamlXContent;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.authz.Permission; import org.elasticsearch.shield.authz.Permission;
import org.elasticsearch.shield.authz.Privilege; import org.elasticsearch.shield.authz.Privilege;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileChangesListener;
import org.elasticsearch.watcher.FileWatcher; import org.elasticsearch.watcher.FileWatcher;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
@ -74,8 +74,7 @@ public class FileRolesStore extends AbstractComponent implements RolesStore {
public static Path resolveFile(Settings settings, Environment env) { public static Path resolveFile(Settings settings, Environment env) {
String location = settings.get("files.roles"); String location = settings.get("files.roles");
if (location == null) { if (location == null) {
File shieldDirectory = new File(env.configFile(), SecurityPlugin.NAME); return ShieldPlugin.resolveConfigFile(env, ".roles.yml");
return shieldDirectory.toPath().resolve(".roles.yml");
} }
return Paths.get(location); return Paths.get(location);

View File

@ -7,15 +7,18 @@ package org.elasticsearch.shield.plugin;
import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.Module;
import org.elasticsearch.env.Environment;
import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.plugins.AbstractPlugin;
import org.elasticsearch.shield.SecurityModule; import org.elasticsearch.shield.ShieldModule;
import java.io.File;
import java.nio.file.Path;
import java.util.Collection; import java.util.Collection;
/** /**
* *
*/ */
public class SecurityPlugin extends AbstractPlugin { public class ShieldPlugin extends AbstractPlugin {
public static final String NAME = "shield"; public static final String NAME = "shield";
@ -31,7 +34,15 @@ public class SecurityPlugin extends AbstractPlugin {
@Override @Override
public Collection<Class<? extends Module>> modules() { public Collection<Class<? extends Module>> modules() {
return ImmutableList.<Class<? extends Module>>of(SecurityModule.class); return ImmutableList.<Class<? extends Module>>of(ShieldModule.class);
}
public static Path configDir(Environment env) {
return new File(env.configFile(), NAME).toPath();
}
public static Path resolveConfigFile(Environment env, String name) {
return configDir(env).resolve(name);
} }
} }

View File

@ -0,0 +1,72 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.support;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.SpawnModules;
import org.elasticsearch.common.settings.Settings;
/**
*
*/
public abstract class AbstractShieldModule extends AbstractModule {
protected final Settings settings;
protected final boolean clientMode;
public AbstractShieldModule(Settings settings) {
this.settings = settings;
this.clientMode = !"node".equals(settings.get(Client.CLIENT_TYPE_SETTING));
}
@Override
protected final void configure() {
configure(clientMode);
}
protected abstract void configure(boolean clientMode);
public static abstract class Spawn extends AbstractShieldModule implements SpawnModules {
protected Spawn(Settings settings) {
super(settings);
}
@Override
public final Iterable<? extends Module> spawnModules() {
return spawnModules(clientMode);
}
public abstract Iterable<? extends Module> spawnModules(boolean clientMode);
}
public static abstract class Node extends AbstractShieldModule {
protected Node(Settings settings) {
super(settings);
}
@Override
protected final void configure(boolean clientMode) {
assert !clientMode : "[" + getClass().getSimpleName() + "] is a node only module";
configureNode();
}
protected abstract void configureNode();
public static abstract class Spawn extends Node implements SpawnModules {
protected Spawn(Settings settings) {
super(settings);
}
public abstract Iterable<? extends AbstractShieldModule.Node> spawnModules();
}
}
}

View File

@ -5,16 +5,21 @@
*/ */
package org.elasticsearch.shield.transport; package org.elasticsearch.shield.transport;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.SecurityFilter; import org.elasticsearch.shield.SecurityFilter;
import org.elasticsearch.shield.support.AbstractShieldModule;
/** /**
* *
*/ */
public class SecuredRestModule extends AbstractModule { public class SecuredRestModule extends AbstractShieldModule.Node {
public SecuredRestModule(Settings settings) {
super(settings);
}
@Override @Override
protected void configure() { protected void configureNode() {
bind(SecurityFilter.Rest.class).asEagerSingleton(); bind(SecurityFilter.Rest.class).asEagerSingleton();
} }
} }

View File

@ -6,12 +6,13 @@
package org.elasticsearch.shield.transport; package org.elasticsearch.shield.transport;
import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule; import org.elasticsearch.common.inject.PreProcessModule;
import org.elasticsearch.common.inject.SpawnModules; import org.elasticsearch.common.inject.util.Providers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.SecurityFilter; import org.elasticsearch.shield.SecurityFilter;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.shield.support.AbstractShieldModule;
import org.elasticsearch.shield.transport.n2n.IPFilteringN2NAuthenticator; import org.elasticsearch.shield.transport.n2n.IPFilteringN2NAuthenticator;
import org.elasticsearch.shield.transport.netty.N2NNettyUpstreamHandler; import org.elasticsearch.shield.transport.netty.N2NNettyUpstreamHandler;
import org.elasticsearch.shield.transport.netty.NettySecuredHttpServerTransportModule; import org.elasticsearch.shield.transport.netty.NettySecuredHttpServerTransportModule;
@ -21,28 +22,46 @@ import org.elasticsearch.transport.TransportModule;
/** /**
* *
*/ */
public class SecuredTransportModule extends AbstractModule implements SpawnModules, PreProcessModule { public class SecuredTransportModule extends AbstractShieldModule.Spawn implements PreProcessModule {
public SecuredTransportModule(Settings settings) {
super(settings);
}
@Override @Override
public Iterable<? extends Module> spawnModules() { public Iterable<? extends Module> spawnModules(boolean clientMode) {
if (clientMode) {
return ImmutableList.of(new NettySecuredTransportModule(settings));
}
//todo we only need to spawn http module if we're not within the transport client context
return ImmutableList.of( return ImmutableList.of(
new NettySecuredHttpServerTransportModule(), new NettySecuredHttpServerTransportModule(settings),
new NettySecuredTransportModule()); new NettySecuredTransportModule(settings));
} }
@Override @Override
public void processModule(Module module) { public void processModule(Module module) {
if (module instanceof TransportModule) { if (module instanceof TransportModule) {
((TransportModule) module).setTransportService(SecuredTransportService.class, SecurityPlugin.NAME); ((TransportModule) module).setTransportService(SecuredTransportService.class, ShieldPlugin.NAME);
} }
} }
@Override @Override
protected void configure() { protected void configure(boolean clientMode) {
if (clientMode) {
// no ip filtering on the client
bind(N2NNettyUpstreamHandler.class).toProvider(Providers.<N2NNettyUpstreamHandler>of(null));
return;
}
bind(TransportFilter.class).to(SecurityFilter.Transport.class).asEagerSingleton(); bind(TransportFilter.class).to(SecurityFilter.Transport.class).asEagerSingleton();
bind(IPFilteringN2NAuthenticator.class).asEagerSingleton(); if (settings.getAsBoolean("shield.transport.n2n.ip_filter.enabled", true)) {
bind(N2NNettyUpstreamHandler.class).asEagerSingleton(); bind(IPFilteringN2NAuthenticator.class).asEagerSingleton();
bind(N2NNettyUpstreamHandler.class).asEagerSingleton();
} else {
bind(N2NNettyUpstreamHandler.class).toProvider(Providers.<N2NNettyUpstreamHandler>of(null));
}
} }
} }

View File

@ -20,7 +20,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.yaml.YamlXContent; import org.elasticsearch.common.xcontent.yaml.YamlXContent;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileChangesListener;
import org.elasticsearch.watcher.FileWatcher; import org.elasticsearch.watcher.FileWatcher;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
@ -60,8 +60,7 @@ public class IPFilteringN2NAuthenticator extends AbstractComponent implements N2
private Path resolveFile(Settings settings, Environment env) { private Path resolveFile(Settings settings, Environment env) {
String location = settings.get("ip_filter.file"); String location = settings.get("ip_filter.file");
if (location == null) { if (location == null) {
File shieldDirectory = new File(env.configFile(), SecurityPlugin.NAME); return ShieldPlugin.resolveConfigFile(env, DEFAULT_FILE);
return shieldDirectory.toPath().resolve(DEFAULT_FILE);
} }
return Paths.get(location); return Paths.get(location);
} }

View File

@ -6,6 +6,7 @@
package org.elasticsearch.shield.transport.netty; package org.elasticsearch.shield.transport.netty;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.internal.Nullable;
import org.elasticsearch.common.netty.channel.ChannelPipeline; import org.elasticsearch.common.netty.channel.ChannelPipeline;
import org.elasticsearch.common.netty.channel.ChannelPipelineFactory; import org.elasticsearch.common.netty.channel.ChannelPipelineFactory;
import org.elasticsearch.common.netty.handler.ssl.SslHandler; import org.elasticsearch.common.netty.handler.ssl.SslHandler;
@ -27,7 +28,7 @@ public class NettySecuredHttpServerTransport extends NettyHttpServerTransport {
@Inject @Inject
public NettySecuredHttpServerTransport(Settings settings, NetworkService networkService, BigArrays bigArrays, public NettySecuredHttpServerTransport(Settings settings, NetworkService networkService, BigArrays bigArrays,
N2NNettyUpstreamHandler shieldUpstreamHandler) { @Nullable N2NNettyUpstreamHandler shieldUpstreamHandler) {
super(settings, networkService, bigArrays); super(settings, networkService, bigArrays);
this.ssl = settings.getAsBoolean("shield.http.ssl", false); this.ssl = settings.getAsBoolean("shield.http.ssl", false);
this.shieldUpstreamHandler = shieldUpstreamHandler; this.shieldUpstreamHandler = shieldUpstreamHandler;
@ -56,7 +57,7 @@ public class NettySecuredHttpServerTransport extends NettyHttpServerTransport {
@Override @Override
public ChannelPipeline getPipeline() throws Exception { public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = super.getPipeline(); ChannelPipeline pipeline = super.getPipeline();
if (settings.getAsBoolean("shield.transport.n2n.ip_filter.enabled", true)) { if (shieldUpstreamHandler != null) {
pipeline.addFirst("ipfilter", shieldUpstreamHandler); pipeline.addFirst("ipfilter", shieldUpstreamHandler);
} }
if (ssl) { if (ssl) {

View File

@ -5,24 +5,30 @@
*/ */
package org.elasticsearch.shield.transport.netty; package org.elasticsearch.shield.transport.netty;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule; import org.elasticsearch.common.inject.PreProcessModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.http.HttpServerModule; import org.elasticsearch.http.HttpServerModule;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.shield.support.AbstractShieldModule;
/** /**
* *
*/ */
public class NettySecuredHttpServerTransportModule extends AbstractModule implements PreProcessModule { public class NettySecuredHttpServerTransportModule extends AbstractShieldModule implements PreProcessModule {
public NettySecuredHttpServerTransportModule(Settings settings) {
super(settings);
}
@Override @Override
public void processModule(Module module) { public void processModule(Module module) {
if (module instanceof HttpServerModule) { if (module instanceof HttpServerModule) {
((HttpServerModule) module).setHttpServerTransport(NettySecuredHttpServerTransport.class, SecurityPlugin.NAME); ((HttpServerModule) module).setHttpServerTransport(NettySecuredHttpServerTransport.class, ShieldPlugin.NAME);
} }
} }
@Override @Override
protected void configure() {} protected void configure(boolean clientMode) {
}
} }

View File

@ -7,6 +7,7 @@ package org.elasticsearch.shield.transport.netty;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.internal.Nullable;
import org.elasticsearch.common.netty.channel.ChannelPipeline; import org.elasticsearch.common.netty.channel.ChannelPipeline;
import org.elasticsearch.common.netty.channel.ChannelPipelineFactory; import org.elasticsearch.common.netty.channel.ChannelPipelineFactory;
import org.elasticsearch.common.netty.handler.ssl.SslHandler; import org.elasticsearch.common.netty.handler.ssl.SslHandler;
@ -29,7 +30,7 @@ public class NettySecuredTransport extends NettyTransport {
@Inject @Inject
public NettySecuredTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version, public NettySecuredTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version,
N2NNettyUpstreamHandler shieldUpstreamHandler) { @Nullable N2NNettyUpstreamHandler shieldUpstreamHandler) {
super(settings, threadPool, networkService, bigArrays, version); super(settings, threadPool, networkService, bigArrays, version);
this.shieldUpstreamHandler = shieldUpstreamHandler; this.shieldUpstreamHandler = shieldUpstreamHandler;
this.ssl = settings.getAsBoolean("shield.transport.ssl", false); this.ssl = settings.getAsBoolean("shield.transport.ssl", false);
@ -63,7 +64,7 @@ public class NettySecuredTransport extends NettyTransport {
@Override @Override
public ChannelPipeline getPipeline() throws Exception { public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = super.getPipeline(); ChannelPipeline pipeline = super.getPipeline();
if (settings.getAsBoolean("shield.transport.n2n.ip_filter.enabled", true)) { if (shieldUpstreamHandler != null) {
pipeline.addFirst("ipfilter", shieldUpstreamHandler); pipeline.addFirst("ipfilter", shieldUpstreamHandler);
} }
if (ssl) { if (ssl) {

View File

@ -5,25 +5,30 @@
*/ */
package org.elasticsearch.shield.transport.netty; package org.elasticsearch.shield.transport.netty;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule; import org.elasticsearch.common.inject.PreProcessModule;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.shield.support.AbstractShieldModule;
import org.elasticsearch.transport.TransportModule; import org.elasticsearch.transport.TransportModule;
/** /**
* *
*/ */
public class NettySecuredTransportModule extends AbstractModule implements PreProcessModule { public class NettySecuredTransportModule extends AbstractShieldModule implements PreProcessModule {
public NettySecuredTransportModule(Settings settings) {
super(settings);
}
@Override @Override
public void processModule(Module module) { public void processModule(Module module) {
if (module instanceof TransportModule) { if (module instanceof TransportModule) {
((TransportModule) module).setTransport(NettySecuredTransport.class, SecurityPlugin.NAME); ((TransportModule) module).setTransport(NettySecuredTransport.class, ShieldPlugin.NAME);
} }
} }
@Override @Override
protected void configure() {} protected void configure(boolean clientMode) {}
} }

View File

@ -1,2 +1,2 @@
plugin=org.elasticsearch.shield.plugin.SecurityPlugin plugin=org.elasticsearch.shield.plugin.ShieldPlugin
version=${project.version} version=${project.version}

View File

@ -24,6 +24,7 @@ public class AuditTrailModuleTests extends ElasticsearchTestCase {
@Test @Test
public void testEnabled() throws Exception { public void testEnabled() throws Exception {
Settings settings = ImmutableSettings.builder() Settings settings = ImmutableSettings.builder()
.put("client.type", "node")
.put("shield.audit.enabled", false) .put("shield.audit.enabled", false)
.build(); .build();
Injector injector = Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings)); Injector injector = Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings));
@ -33,7 +34,8 @@ public class AuditTrailModuleTests extends ElasticsearchTestCase {
@Test @Test
public void testDisabledByDefault() throws Exception { public void testDisabledByDefault() throws Exception {
Settings settings = ImmutableSettings.EMPTY; Settings settings = ImmutableSettings.builder()
.put("client.type", "node").build();
Injector injector = Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings)); Injector injector = Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings));
AuditTrail auditTrail = injector.getInstance(AuditTrail.class); AuditTrail auditTrail = injector.getInstance(AuditTrail.class);
assertThat(auditTrail, is(AuditTrail.NOOP)); assertThat(auditTrail, is(AuditTrail.NOOP));
@ -43,6 +45,7 @@ public class AuditTrailModuleTests extends ElasticsearchTestCase {
public void testLogfile() throws Exception { public void testLogfile() throws Exception {
Settings settings = ImmutableSettings.builder() Settings settings = ImmutableSettings.builder()
.put("shield.audit.enabled", true) .put("shield.audit.enabled", true)
.put("client.type", "node")
.build(); .build();
Injector injector = Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings)); Injector injector = Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings));
AuditTrail auditTrail = injector.getInstance(AuditTrail.class); AuditTrail auditTrail = injector.getInstance(AuditTrail.class);
@ -58,6 +61,7 @@ public class AuditTrailModuleTests extends ElasticsearchTestCase {
Settings settings = ImmutableSettings.builder() Settings settings = ImmutableSettings.builder()
.put("shield.audit.enabled", true) .put("shield.audit.enabled", true)
.put("shield.audit.outputs" , "foo") .put("shield.audit.outputs" , "foo")
.put("client.type", "node")
.build(); .build();
try { try {
Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings)); Guice.createInjector(new SettingsModule(settings), new AuditTrailModule(settings));

View File

@ -11,6 +11,7 @@ import org.elasticsearch.common.inject.Injector;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
@ -21,6 +22,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.mock;
/** /**
* *
@ -38,7 +40,8 @@ public class ESUsersModuleTests extends ElasticsearchTestCase {
@Test @Test
public void test() throws Exception { public void test() throws Exception {
Injector injector = Guice.createInjector(new TestModule(users, usersRoles), new ESUsersModule()); Settings settings = ImmutableSettings.builder().put("client.type", "node").build();
Injector injector = Guice.createInjector(new TestModule(users, usersRoles), new ESUsersModule(settings));
ESUsersRealm realm = injector.getInstance(ESUsersRealm.class); ESUsersRealm realm = injector.getInstance(ESUsersRealm.class);
assertThat(realm, notNullValue()); assertThat(realm, notNullValue());
assertThat(realm.userPasswdStore, notNullValue()); assertThat(realm.userPasswdStore, notNullValue());
@ -81,6 +84,7 @@ public class ESUsersModuleTests extends ElasticsearchTestCase {
bind(Environment.class).toInstance(env); bind(Environment.class).toInstance(env);
bind(ThreadPool.class).toInstance(new ThreadPool("test")); bind(ThreadPool.class).toInstance(new ThreadPool("test"));
bind(ResourceWatcherService.class).asEagerSingleton(); bind(ResourceWatcherService.class).asEagerSingleton();
bind(RestController.class).toInstance(mock(RestController.class));
} }
} }

View File

@ -13,12 +13,13 @@ import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.client.ClusterAdminClient; import org.elasticsearch.client.ClusterAdminClient;
import org.elasticsearch.client.IndicesAdminClient; import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.SecurityFilter;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.support.UserPasswdStore; import org.elasticsearch.shield.authc.support.UserPasswdStore;
import org.elasticsearch.shield.authc.support.UserRolesStore; import org.elasticsearch.shield.authc.support.UserRolesStore;
@ -26,25 +27,41 @@ import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.transport.TransportRequest;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.arrayContaining;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.*;
import static org.mockito.Mockito.when;
/** /**
* *
*/ */
public class ESUsersRealmTests extends ElasticsearchTestCase { public class ESUsersRealmTests extends ElasticsearchTestCase {
private RestController restController;
private Client client;
private AdminClient adminClient;
@Before
public void init() throws Exception {
client = mock(Client.class);
adminClient = mock(AdminClient.class);
restController = mock(RestController.class);
}
@Test
public void testRestHeaderRegistration() {
new ESUsersRealm(ImmutableSettings.EMPTY, mock(UserPasswdStore.class), mock(UserRolesStore.class), restController);
verify(restController).registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
}
@Test @Test
public void testAuthenticate() throws Exception { public void testAuthenticate() throws Exception {
Settings settings = ImmutableSettings.builder().build(); Settings settings = ImmutableSettings.builder().build();
MockUserPasswdStore userPasswdStore = new MockUserPasswdStore("user1", "test123"); MockUserPasswdStore userPasswdStore = new MockUserPasswdStore("user1", "test123");
MockUserRolesStore userRolesStore = new MockUserRolesStore("user1", "role1", "role2"); MockUserRolesStore userRolesStore = new MockUserRolesStore("user1", "role1", "role2");
ESUsersRealm realm = new ESUsersRealm(settings, userPasswdStore, userRolesStore); ESUsersRealm realm = new ESUsersRealm(settings, userPasswdStore, userRolesStore, restController);
User user = realm.authenticate(new UsernamePasswordToken("user1", "test123".toCharArray())); User user = realm.authenticate(new UsernamePasswordToken("user1", "test123".toCharArray()));
assertTrue(userPasswdStore.called); assertTrue(userPasswdStore.called);
assertTrue(userRolesStore.called); assertTrue(userRolesStore.called);
@ -60,7 +77,7 @@ public class ESUsersRealmTests extends ElasticsearchTestCase {
Settings settings = ImmutableSettings.builder().build(); Settings settings = ImmutableSettings.builder().build();
MockUserPasswdStore userPasswdStore = new MockUserPasswdStore("user1", "test123"); MockUserPasswdStore userPasswdStore = new MockUserPasswdStore("user1", "test123");
MockUserRolesStore userRolesStore = new MockUserRolesStore("user1", "role1", "role2"); MockUserRolesStore userRolesStore = new MockUserRolesStore("user1", "role1", "role2");
ESUsersRealm realm = new ESUsersRealm(settings, userPasswdStore, userRolesStore); ESUsersRealm realm = new ESUsersRealm(settings, userPasswdStore, userRolesStore, restController);
TransportRequest request = new TransportRequest() {}; TransportRequest request = new TransportRequest() {};
UsernamePasswordToken.putTokenHeader(request, new UsernamePasswordToken("user1", "test123".toCharArray())); UsernamePasswordToken.putTokenHeader(request, new UsernamePasswordToken("user1", "test123".toCharArray()));
@ -116,9 +133,8 @@ public class ESUsersRealmTests extends ElasticsearchTestCase {
@Test @SuppressWarnings("unchecked") @Test @SuppressWarnings("unchecked")
public void testRestHeadersAreCopied() throws Exception { public void testRestHeadersAreCopied() throws Exception {
// the required header will be registered only if ESUsersRealm is actually used. // the required header will be registered only if ESUsersRealm is actually used.
new ESUsersRealm(ImmutableSettings.EMPTY, null, null); new ESUsersRealm(ImmutableSettings.EMPTY, null, null, restController);
Client client = mock(Client.class); when(restController.relevantHeaders()).thenReturn(ImmutableSet.of(UsernamePasswordToken.BASIC_AUTH_HEADER));
AdminClient adminClient = mock(AdminClient.class);
when(client.admin()).thenReturn(adminClient); when(client.admin()).thenReturn(adminClient);
when(adminClient.cluster()).thenReturn(mock(ClusterAdminClient.class)); when(adminClient.cluster()).thenReturn(mock(ClusterAdminClient.class));
when(adminClient.indices()).thenReturn(mock(IndicesAdminClient.class)); when(adminClient.indices()).thenReturn(mock(IndicesAdminClient.class));
@ -128,15 +144,16 @@ public class ESUsersRealmTests extends ElasticsearchTestCase {
return null; return null;
} }
}; };
RestRequest restRequest = mock(RestRequest.class);
final Action action = mock(Action.class); final Action action = mock(Action.class);
final ActionListener listener = mock(ActionListener.class); final ActionListener listener = mock(ActionListener.class);
BaseRestHandler handler = new BaseRestHandler(ImmutableSettings.EMPTY, client) { BaseRestHandler handler = new BaseRestHandler(ImmutableSettings.EMPTY, restController, client) {
@Override @Override
protected void handleRequest(RestRequest restRequest, RestChannel channel, Client client) throws Exception { protected void handleRequest(RestRequest restRequest, RestChannel channel, Client client) throws Exception {
client.execute(action, request, listener); client.execute(action, request, listener);
} }
}; };
RestRequest restRequest = mock(RestRequest.class);
when(restRequest.header(UsernamePasswordToken.BASIC_AUTH_HEADER)).thenReturn("foobar"); when(restRequest.header(UsernamePasswordToken.BASIC_AUTH_HEADER)).thenReturn("foobar");
RestChannel channel = mock(RestChannel.class); RestChannel channel = mock(RestChannel.class);
handler.handleRequest(restRequest, channel); handler.handleRequest(restRequest, channel);

View File

@ -8,11 +8,13 @@ package org.elasticsearch.shield.authc.ldap;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.support.UsernamePasswordToken; import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.ResourceWatcherService;
import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -31,9 +33,22 @@ public class LdapRealmTest extends ElasticsearchTestCase {
public static final String VALID_USERNAME = "Thomas Masterman Hardy"; public static final String VALID_USERNAME = "Thomas Masterman Hardy";
public static final String PASSWORD = "pass"; public static final String PASSWORD = "pass";
private RestController restController;
@Before
public void init() throws Exception {
restController = mock(RestController.class);
}
@Rule @Rule
public static ApacheDsRule apacheDsRule = new ApacheDsRule(); public static ApacheDsRule apacheDsRule = new ApacheDsRule();
@Test
public void testRestHeaderRegistration() {
new LdapRealm(ImmutableSettings.EMPTY, mock(LdapConnectionFactory.class), mock(LdapGroupToRoleMapper.class), restController);
verify(restController).registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
}
@Test @Test
public void testAuthenticate_subTreeGroupSearch(){ public void testAuthenticate_subTreeGroupSearch(){
String groupSearchBase = "o=sevenSeas"; String groupSearchBase = "o=sevenSeas";
@ -41,7 +56,7 @@ public class LdapRealmTest extends ElasticsearchTestCase {
String userTemplate = VALID_USER_TEMPLATE; String userTemplate = VALID_USER_TEMPLATE;
Settings settings = LdapConnectionTests.buildLdapSettings(apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch); Settings settings = LdapConnectionTests.buildLdapSettings(apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch);
StandardLdapConnectionFactory ldapFactory = new StandardLdapConnectionFactory(settings); StandardLdapConnectionFactory ldapFactory = new StandardLdapConnectionFactory(settings);
LdapRealm ldap = new LdapRealm(buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper()); LdapRealm ldap = new LdapRealm(buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper(), restController);
User user = ldap.authenticate(new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray())); User user = ldap.authenticate(new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray()));
assertThat( user, notNullValue()); assertThat( user, notNullValue());
@ -56,7 +71,7 @@ public class LdapRealmTest extends ElasticsearchTestCase {
StandardLdapConnectionFactory ldapFactory = new StandardLdapConnectionFactory( StandardLdapConnectionFactory ldapFactory = new StandardLdapConnectionFactory(
LdapConnectionTests.buildLdapSettings(apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch)); LdapConnectionTests.buildLdapSettings(apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch));
LdapRealm ldap = new LdapRealm(buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper()); LdapRealm ldap = new LdapRealm(buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper(), restController);
User user = ldap.authenticate(new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray())); User user = ldap.authenticate(new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray()));
assertThat( user, notNullValue()); assertThat( user, notNullValue());
@ -73,7 +88,7 @@ public class LdapRealmTest extends ElasticsearchTestCase {
LdapConnectionTests.buildLdapSettings( apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch) ); LdapConnectionTests.buildLdapSettings( apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch) );
ldapFactory = spy(ldapFactory); ldapFactory = spy(ldapFactory);
LdapRealm ldap = new LdapRealm( buildCachingSettings(), ldapFactory, buildGroupAsRoleMapper()); LdapRealm ldap = new LdapRealm( buildCachingSettings(), ldapFactory, buildGroupAsRoleMapper(), restController);
User user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray())); User user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray()));
user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray())); user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray()));
@ -90,7 +105,7 @@ public class LdapRealmTest extends ElasticsearchTestCase {
LdapConnectionTests.buildLdapSettings(apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch) ); LdapConnectionTests.buildLdapSettings(apacheDsRule.getUrl(), userTemplate, groupSearchBase, isSubTreeSearch) );
ldapFactory = spy(ldapFactory); ldapFactory = spy(ldapFactory);
LdapRealm ldap = new LdapRealm( buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper()); LdapRealm ldap = new LdapRealm( buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper(), restController);
User user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray())); User user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray()));
user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray())); user = ldap.authenticate( new UsernamePasswordToken(VALID_USERNAME, PASSWORD.toCharArray()));
@ -107,7 +122,7 @@ public class LdapRealmTest extends ElasticsearchTestCase {
ActiveDirectoryConnectionFactory ldapFactory = new ActiveDirectoryConnectionFactory( ActiveDirectoryConnectionFactory ldapFactory = new ActiveDirectoryConnectionFactory(
ActiveDirectoryFactoryTests.buildAdSettings(AD_URL, adDomain)); ActiveDirectoryFactoryTests.buildAdSettings(AD_URL, adDomain));
LdapRealm ldap = new LdapRealm( buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper()); LdapRealm ldap = new LdapRealm( buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper(), restController);
User user = ldap.authenticate( new UsernamePasswordToken("george", "R))Tr0x".toCharArray())); User user = ldap.authenticate( new UsernamePasswordToken("george", "R))Tr0x".toCharArray()));
@ -125,7 +140,7 @@ public class LdapRealmTest extends ElasticsearchTestCase {
.build(); .build();
ActiveDirectoryConnectionFactory ldapFactory = new ActiveDirectoryConnectionFactory( settings ); ActiveDirectoryConnectionFactory ldapFactory = new ActiveDirectoryConnectionFactory( settings );
LdapRealm ldap = new LdapRealm( buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper()); LdapRealm ldap = new LdapRealm( buildNonCachingSettings(), ldapFactory, buildGroupAsRoleMapper(), restController);
User user = ldap.authenticate( new UsernamePasswordToken("george", "R))Tr0x".toCharArray())); User user = ldap.authenticate( new UsernamePasswordToken("george", "R))Tr0x".toCharArray()));
assertThat( user, notNullValue()); assertThat( user, notNullValue());

View File

@ -22,7 +22,7 @@ public class ShieldPluginTests extends ShieldIntegrationTest {
logger.info("--> Checking nodes info that shield plugin is loaded"); logger.info("--> Checking nodes info that shield plugin is loaded");
for (NodeInfo nodeInfo : nodeInfos.getNodes()) { for (NodeInfo nodeInfo : nodeInfos.getNodes()) {
assertThat(nodeInfo.getPlugins().getInfos(), hasSize(1)); assertThat(nodeInfo.getPlugins().getInfos(), hasSize(1));
assertThat(nodeInfo.getPlugins().getInfos().get(0).getName(), is(SecurityPlugin.NAME)); assertThat(nodeInfo.getPlugins().getInfos().get(0).getName(), is(ShieldPlugin.NAME));
} }
} }

View File

@ -6,17 +6,17 @@
package org.elasticsearch.shield.test; package org.elasticsearch.shield.test;
import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.SecurityException; import org.elasticsearch.shield.ShieldException;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
public class ShieldAssertions { public class ShieldAssertions {
public static void assertContainsWWWAuthenticateHeader(org.elasticsearch.shield.SecurityException e) { public static void assertContainsWWWAuthenticateHeader(ShieldException e) {
assertThat(e.status(), is(RestStatus.UNAUTHORIZED)); assertThat(e.status(), is(RestStatus.UNAUTHORIZED));
assertThat(e.getHeaders(), hasKey("WWW-Authenticate")); assertThat(e.getHeaders(), hasKey("WWW-Authenticate"));
assertThat(e.getHeaders().get("WWW-Authenticate"), hasSize(1)); assertThat(e.getHeaders().get("WWW-Authenticate"), hasSize(1));
assertThat(e.getHeaders().get("WWW-Authenticate").get(0), is(SecurityException.HEADERS.get("WWW-Authenticate").get(0))); assertThat(e.getHeaders().get("WWW-Authenticate").get(0), is(ShieldException.HEADERS.get("WWW-Authenticate").get(0)));
} }
} }

View File

@ -15,7 +15,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.plugins.PluginsService; import org.elasticsearch.plugins.PluginsService;
import org.elasticsearch.shield.plugin.SecurityPlugin; import org.elasticsearch.shield.plugin.ShieldPlugin;
import org.elasticsearch.shield.transport.netty.NettySecuredTransport; import org.elasticsearch.shield.transport.netty.NettySecuredTransport;
import org.elasticsearch.test.ElasticsearchIntegrationTest; import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.Transport;
@ -65,7 +65,7 @@ public abstract class ShieldIntegrationTest extends ElasticsearchIntegrationTest
.put("discovery.zen.ping.multicast.enabled", false) .put("discovery.zen.ping.multicast.enabled", false)
.put("discovery.type", "zen") .put("discovery.type", "zen")
.put("node.mode", "network") .put("node.mode", "network")
.put("plugin.types", SecurityPlugin.class.getName()) .put("plugin.types", ShieldPlugin.class.getName())
.put("shield.authc.esusers.files.users", writeFile(folder, "users", CONFIG_STANDARD_USER)) .put("shield.authc.esusers.files.users", writeFile(folder, "users", CONFIG_STANDARD_USER))
.put("shield.authc.esusers.files.users_roles", writeFile(folder, "users_roles", CONFIG_STANDARD_USER_ROLES)) .put("shield.authc.esusers.files.users_roles", writeFile(folder, "users_roles", CONFIG_STANDARD_USER_ROLES))
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", CONFIG_ROLE_ALLOW_ALL)) .put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", CONFIG_ROLE_ALLOW_ALL))

View File

@ -25,6 +25,7 @@ indices:admin/cache/clear
indices:admin/close indices:admin/close
indices:admin/create indices:admin/create
indices:admin/delete indices:admin/delete
indices:admin/get
indices:admin/exists indices:admin/exists
indices:admin/flush indices:admin/flush
indices:admin/mapping/delete indices:admin/mapping/delete