diff --git a/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/ExampleRealmExtension.java b/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/ExampleRealmExtension.java index c859489e5ee..86d4091a08e 100644 --- a/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/ExampleRealmExtension.java +++ b/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/ExampleRealmExtension.java @@ -7,16 +7,27 @@ package org.elasticsearch.example; import org.elasticsearch.example.realm.CustomAuthenticationFailureHandler; import org.elasticsearch.example.realm.CustomRealm; -import org.elasticsearch.example.realm.CustomRealmFactory; import org.elasticsearch.xpack.security.authc.AuthenticationModule; import org.elasticsearch.xpack.extensions.XPackExtension; +import org.elasticsearch.xpack.security.authc.Realm; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Map; public class ExampleRealmExtension extends XPackExtension { + + static { + // check that the extension's policy works. + AccessController.doPrivileged((PrivilegedAction) () -> { + System.getSecurityManager().checkPrintJobAccess(); + return null; + }); + } + @Override public String name() { return "custom realm example"; @@ -28,13 +39,12 @@ public class ExampleRealmExtension extends XPackExtension { } public void onModule(AuthenticationModule authenticationModule) { - authenticationModule.addCustomRealm(CustomRealm.TYPE, CustomRealmFactory.class); authenticationModule.setAuthenticationFailureHandler(CustomAuthenticationFailureHandler.class); - // check that the extension's policy works. - AccessController.doPrivileged((PrivilegedAction) () -> { - System.getSecurityManager().checkPrintJobAccess(); - return null; - }); + } + + @Override + public Map getRealms() { + return Collections.singletonMap(CustomRealm.TYPE, CustomRealm::new); } @Override diff --git a/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealm.java b/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealm.java index f1cc2dc9a80..aee93517fdd 100644 --- a/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealm.java +++ b/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealm.java @@ -13,7 +13,7 @@ import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; -public class CustomRealm extends Realm { +public class CustomRealm extends Realm { public static final String TYPE = "custom"; @@ -46,7 +46,8 @@ public class CustomRealm extends Realm { } @Override - public User authenticate(UsernamePasswordToken token) { + public User authenticate(AuthenticationToken authToken) { + UsernamePasswordToken token = (UsernamePasswordToken)authToken; final String actualUser = token.principal(); if (KNOWN_USER.equals(actualUser) && SecuredString.constantTimeEquals(token.credentials(), KNOWN_PW)) { return new User(actualUser, ROLES); diff --git a/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealmFactory.java b/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealmFactory.java deleted file mode 100644 index b1f65bbeccf..00000000000 --- a/elasticsearch/qa/security-example-realm/src/main/java/org/elasticsearch/example/realm/CustomRealmFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.example.realm; - -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.rest.RestController; -import org.elasticsearch.xpack.security.authc.Realm; -import org.elasticsearch.xpack.security.authc.RealmConfig; - -public class CustomRealmFactory extends Realm.Factory { - - @Inject - public CustomRealmFactory() { - super(CustomRealm.TYPE, false); - } - - @Override - public CustomRealm create(RealmConfig config) { - return new CustomRealm(config); - } - - @Override - public CustomRealm createDefault(String name) { - return null; - } -} diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java index aa0764b9458..faeaeebfee5 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -36,8 +37,10 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.rest.RestHandler; +import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.XPackPlugin; +import org.elasticsearch.xpack.extensions.XPackExtension; import org.elasticsearch.xpack.security.action.SecurityActionModule; import org.elasticsearch.xpack.security.action.filter.SecurityActionFilter; import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheAction; @@ -63,11 +66,20 @@ import org.elasticsearch.xpack.security.action.user.TransportPutUserAction; import org.elasticsearch.xpack.security.audit.AuditTrailModule; import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail; import org.elasticsearch.xpack.security.audit.index.IndexNameResolver; +import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler; import org.elasticsearch.xpack.security.authc.AuthenticationModule; +import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler; import org.elasticsearch.xpack.security.authc.InternalAuthenticationService; +import org.elasticsearch.xpack.security.authc.Realm; import org.elasticsearch.xpack.security.authc.Realms; +import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; +import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore; +import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; +import org.elasticsearch.xpack.security.authc.file.FileRealm; +import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory; +import org.elasticsearch.xpack.security.authc.pki.PkiRealm; import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; import org.elasticsearch.xpack.security.authz.AuthorizationModule; @@ -197,11 +209,11 @@ public class Security implements ActionPlugin { } List> list = new ArrayList<>(); list.add(FileRolesStore.class); - list.add(Realms.class); return list; } - public Collection createComponents(ResourceWatcherService resourceWatcherService) { + public Collection createComponents(InternalClient client, ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, List extensions) { if (enabled == false) { return Collections.emptyList(); } @@ -210,7 +222,27 @@ public class Security implements ActionPlugin { final ClientSSLService clientSSLService = new ClientSSLService(settings, env, globalSslConfig, resourceWatcherService); final ServerSSLService serverSSLService = new ServerSSLService(settings, env, globalSslConfig, resourceWatcherService); - return Arrays.asList(clientSSLService, serverSSLService); + // realms construction + final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, threadPool); + final ReservedRealm reservedRealm = new ReservedRealm(env, settings, nativeUsersStore); + Map realmFactories = new HashMap<>(); + realmFactories.put(FileRealm.TYPE, config -> new FileRealm(config, resourceWatcherService)); + realmFactories.put(NativeRealm.TYPE, config -> new NativeRealm(config, nativeUsersStore)); + realmFactories.put(ActiveDirectoryRealm.TYPE, + config -> new ActiveDirectoryRealm(config, resourceWatcherService, clientSSLService)); + realmFactories.put(LdapRealm.TYPE, config -> new LdapRealm(config, resourceWatcherService, clientSSLService)); + realmFactories.put(PkiRealm.TYPE, config -> new PkiRealm(config, resourceWatcherService)); + for (XPackExtension extension : extensions) { + Map newRealms = extension.getRealms(); + for (Map.Entry entry : newRealms.entrySet()) { + if (realmFactories.put(entry.getKey(), entry.getValue()) != null) { + throw new IllegalArgumentException("Realm type [" + entry.getKey() + "] is already registered"); + } + } + } + final Realms realms = new Realms(settings, env, realmFactories, securityLicenseState, reservedRealm); + + return Arrays.asList(clientSSLService, serverSSLService, nativeUsersStore, realms); } public Settings additionalSettings() { diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationModule.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationModule.java index afdf6f563c2..57491d0c12e 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationModule.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationModule.java @@ -5,36 +5,16 @@ */ package org.elasticsearch.xpack.security.authc; -import org.elasticsearch.common.inject.multibindings.MapBinder; import org.elasticsearch.common.inject.util.Providers; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; -import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; -import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore; -import org.elasticsearch.xpack.security.authc.file.FileRealm; -import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; -import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; -import org.elasticsearch.xpack.security.authc.pki.PkiRealm; import org.elasticsearch.xpack.security.support.AbstractSecurityModule; import org.elasticsearch.xpack.security.user.AnonymousUser; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - /** * */ public class AuthenticationModule extends AbstractSecurityModule.Node { - static final List INTERNAL_REALM_TYPES = - Arrays.asList(ReservedRealm.TYPE, NativeRealm.TYPE, FileRealm.TYPE, ActiveDirectoryRealm.TYPE, LdapRealm.TYPE, PkiRealm.TYPE); - - private final Map>>> customRealms = - new HashMap<>(); - private Class authcFailureHandler = null; public AuthenticationModule(Settings settings) { @@ -49,45 +29,14 @@ public class AuthenticationModule extends AbstractSecurityModule.Node { } AnonymousUser.initialize(settings); - MapBinder mapBinder = MapBinder.newMapBinder(binder(), String.class, Realm.Factory.class); - mapBinder.addBinding(FileRealm.TYPE).to(FileRealm.Factory.class).asEagerSingleton(); - mapBinder.addBinding(NativeRealm.TYPE).to(NativeRealm.Factory.class).asEagerSingleton(); - mapBinder.addBinding(ActiveDirectoryRealm.TYPE).to(ActiveDirectoryRealm.Factory.class).asEagerSingleton(); - mapBinder.addBinding(LdapRealm.TYPE).to(LdapRealm.Factory.class).asEagerSingleton(); - mapBinder.addBinding(PkiRealm.TYPE).to(PkiRealm.Factory.class).asEagerSingleton(); - for (Entry>>> entry : - customRealms.entrySet()) { - mapBinder.addBinding(entry.getKey()).to(entry.getValue()).asEagerSingleton(); - } - - bind(ReservedRealm.class).asEagerSingleton(); - bind(Realms.class).asEagerSingleton(); if (authcFailureHandler == null) { bind(AuthenticationFailureHandler.class).to(DefaultAuthenticationFailureHandler.class).asEagerSingleton(); } else { bind(AuthenticationFailureHandler.class).to(authcFailureHandler).asEagerSingleton(); } - bind(NativeUsersStore.class).asEagerSingleton(); bind(AuthenticationService.class).to(InternalAuthenticationService.class).asEagerSingleton(); } - /** - * Registers a custom realm type and factory for use as a authentication realm - * - * @param type the type of the realm that identifies it. Must not be null, empty, or the same value as one of the built-in realms - * @param clazz the factory class that is used to create this type of realm. Must not be null - */ - public void addCustomRealm(String type, Class>> clazz) { - if (type == null || type.isEmpty()) { - throw new IllegalArgumentException("type must not be null or empty"); - } else if (clazz == null) { - throw new IllegalArgumentException("realm factory class cannot be null"); - } else if (INTERNAL_REALM_TYPES.contains(type)) { - throw new IllegalArgumentException("cannot redefine the type [" + type + "] with custom realm [" + clazz.getName() + "]"); - } - customRealms.put(type, clazz); - } - /** * Sets the {@link AuthenticationFailureHandler} to the specified implementation */ diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java index dd5a9f404c3..078ff26c76e 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java @@ -17,7 +17,7 @@ import java.util.Map; * service } delegates the authentication process. Different realms may be defined, each may be based on different * authentication mechanism supporting its own specific authentication token type. */ -public abstract class Realm implements Comparable { +public abstract class Realm implements Comparable { protected final ESLogger logger; protected final String type; @@ -67,7 +67,7 @@ public abstract class Realm implements Comparable * @param context The context that will provide information about the incoming request * @return The authentication token or {@code null} if not found */ - public abstract T token(ThreadContext context); + public abstract AuthenticationToken token(ThreadContext context); /** * Authenticates the given token. A successful authentication will return the User associated @@ -76,7 +76,7 @@ public abstract class Realm implements Comparable * @param token The authentication token * @return The authenticated user or {@code null} if authentication failed. */ - public abstract User authenticate(T token); + public abstract User authenticate(AuthenticationToken token); /** * Looks up the user identified the String identifier. A successful lookup will return the {@link User} identified @@ -107,44 +107,14 @@ public abstract class Realm implements Comparable } /** - * A factory for a specific realm type. Knows how to create a new realm given the appropriate - * settings. The factory will be called when creating a realm during the parsing of realms defined in the - * elasticsearch.yml file + * A factory interface to construct a security realm. */ - public abstract static class Factory { - - private final String type; - private final boolean internal; - - public Factory(String type, boolean internal) { - this.type = type; - this.internal = internal; - } + public interface Factory { /** - * @return The type of the ream this factory creates + * Constructs a realm which will be used for authentication. + * @param config The configuration for the realm */ - public String type() { - return type; - } - - public boolean internal() { - return internal; - } - - /** - * Creates a new realm based on the given settigns. - * - * @param config The configuration for the realm - * @return The new realm (this method never returns {@code null}). - */ - public abstract R create(RealmConfig config); - - /** - * Creates a default realm, one that has no custom settings. Some realms might require minimal - * settings, in which case, this method will return {@code null}. - */ - public abstract R createDefault(String name); + Realm create(RealmConfig config); } - } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java index 470c664f2e1..2fda12f8b42 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java @@ -13,10 +13,13 @@ import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.xpack.security.SecurityLicenseState.EnabledRealmType; +import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; import org.elasticsearch.xpack.security.authc.file.FileRealm; import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; +import org.elasticsearch.xpack.security.authc.pki.PkiRealm; import java.util.ArrayList; import java.util.Arrays; @@ -34,6 +37,9 @@ import static org.elasticsearch.xpack.security.Security.setting; */ public class Realms extends AbstractLifecycleComponent implements Iterable { + static final List INTERNAL_REALM_TYPES = + Arrays.asList(ReservedRealm.TYPE, NativeRealm.TYPE, FileRealm.TYPE, ActiveDirectoryRealm.TYPE, LdapRealm.TYPE, PkiRealm.TYPE); + public static final Setting REALMS_GROUPS_SETTINGS = Setting.groupSetting(setting("authc.realms."), Property.NodeScope); private final Environment env; @@ -47,7 +53,6 @@ public class Realms extends AbstractLifecycleComponent implements Iterable nativeRealmsOnly = Collections.emptyList(); - @Inject public Realms(Settings settings, Environment env, Map factories, SecurityLicenseState securityLicenseState, ReservedRealm reservedRealm) { super(settings); @@ -67,7 +72,7 @@ public class Realms extends AbstractLifecycleComponent implements Iterable nativeRealms = new ArrayList<>(); for (Realm realm : realms) { // don't add the reserved realm here otherwise we end up with only this realm... - if (AuthenticationModule.INTERNAL_REALM_TYPES.contains(realm.type()) && ReservedRealm.TYPE.equals(realm.type()) == false) { + if (INTERNAL_REALM_TYPES.contains(realm.type()) && ReservedRealm.TYPE.equals(realm.type()) == false) { internalRealms.add(realm); } @@ -151,7 +156,7 @@ public class Realms extends AbstractLifecycleComponent implements Iterable realms) { Realm.Factory fileRealm = factories.get(FileRealm.TYPE); if (fileRealm != null) { - realms.add(fileRealm.createDefault("default_" + FileRealm.TYPE)); + + realms.add(fileRealm.create(new RealmConfig("default_" + FileRealm.TYPE, Settings.EMPTY, settings, env))); } Realm.Factory indexRealmFactory = factories.get(NativeRealm.TYPE); if (indexRealmFactory != null) { - realms.add(indexRealmFactory.createDefault("default_" + NativeRealm.TYPE)); + realms.add(indexRealmFactory.create(new RealmConfig("default_" + NativeRealm.TYPE, Settings.EMPTY, settings, env))); } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealm.java index 1596ba47d53..19a72fe90d5 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealm.java @@ -5,13 +5,12 @@ */ package org.elasticsearch.xpack.security.authc.activedirectory; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.rest.RestController; +import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.ldap.support.AbstractLdapRealm; +import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory; import org.elasticsearch.xpack.security.authc.support.DnRoleMapper; import org.elasticsearch.xpack.security.ssl.ClientSSLService; -import org.elasticsearch.watcher.ResourceWatcherService; /** * @@ -20,30 +19,13 @@ public class ActiveDirectoryRealm extends AbstractLdapRealm { public static final String TYPE = "active_directory"; - public ActiveDirectoryRealm(RealmConfig config, - ActiveDirectorySessionFactory connectionFactory, - DnRoleMapper roleMapper) { - - super(TYPE, config, connectionFactory, roleMapper); + public ActiveDirectoryRealm(RealmConfig config, ResourceWatcherService watcherService, ClientSSLService clientSSLService) { + this(config, new ActiveDirectorySessionFactory(config, clientSSLService).init(), + new DnRoleMapper(TYPE, config, watcherService, null)); } - public static class Factory extends AbstractLdapRealm.Factory { - - private final ResourceWatcherService watcherService; - private final ClientSSLService clientSSLService; - - @Inject - public Factory(ResourceWatcherService watcherService, ClientSSLService clientSSLService) { - super(ActiveDirectoryRealm.TYPE); - this.watcherService = watcherService; - this.clientSSLService = clientSSLService; - } - - @Override - public ActiveDirectoryRealm create(RealmConfig config) { - ActiveDirectorySessionFactory connectionFactory = new ActiveDirectorySessionFactory(config, clientSSLService).init(); - DnRoleMapper roleMapper = new DnRoleMapper(TYPE, config, watcherService, null); - return new ActiveDirectoryRealm(config, connectionFactory, roleMapper); - } + // pkg private for tests + ActiveDirectoryRealm(RealmConfig config, SessionFactory sessionFactory, DnRoleMapper roleMapper) { + super(TYPE, config, sessionFactory, roleMapper); } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealm.java index be8b2a65250..e018c5e3ac8 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealm.java @@ -5,19 +5,12 @@ */ package org.elasticsearch.xpack.security.authc.esnative; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Property; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.env.Environment; -import org.elasticsearch.xpack.security.user.User; -import org.elasticsearch.xpack.security.authc.Realm; +import java.util.List; + import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; - -import java.util.List; +import org.elasticsearch.xpack.security.user.User; /** * User/password realm that is backed by an Elasticsearch index @@ -58,30 +51,4 @@ public class NativeRealm extends CachingUsernamePasswordRealm { } } } - - public static class Factory extends Realm.Factory { - - private final Settings settings; - private final Environment env; - private final NativeUsersStore userStore; - - @Inject - public Factory(Settings settings, Environment env, NativeUsersStore userStore) { - super(TYPE, true); - this.settings = settings; - this.env = env; - this.userStore = userStore; - } - - @Override - public NativeRealm create(RealmConfig config) { - return new NativeRealm(config, userStore); - } - - @Override - public NativeRealm createDefault(String name) { - RealmConfig config = new RealmConfig(name, Settings.EMPTY, settings, env); - return create(config); - } - } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java index 78af963ca9c..e8e3ea3e08b 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java @@ -123,7 +123,6 @@ public class NativeUsersStore extends AbstractComponent implements ClusterStateL private volatile boolean securityIndexExists = false; - @Inject public NativeUsersStore(Settings settings, InternalClient client, ThreadPool threadPool) { super(settings); this.client = client; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ReservedRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ReservedRealm.java index 52aa20550af..4dbafd1b39d 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ReservedRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ReservedRealm.java @@ -35,7 +35,6 @@ public class ReservedRealm extends CachingUsernamePasswordRealm { private final NativeUsersStore nativeUsersStore; - @Inject public ReservedRealm(Environment env, Settings settings, NativeUsersStore nativeUsersStore) { super(TYPE, new RealmConfig(TYPE, Settings.EMPTY, settings, env)); this.nativeUsersStore = nativeUsersStore; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java index a582f76931f..bd17724107c 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java @@ -5,19 +5,14 @@ */ package org.elasticsearch.xpack.security.authc.file; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.Environment; -import org.elasticsearch.rest.RestController; +import java.util.Map; + +import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm; import org.elasticsearch.xpack.security.authc.support.RefreshListener; -import org.elasticsearch.xpack.security.authc.support.UsernamePasswordRealm; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; import org.elasticsearch.xpack.security.user.User; -import org.elasticsearch.watcher.ResourceWatcherService; - -import java.util.Map; /** * @@ -29,7 +24,12 @@ public class FileRealm extends CachingUsernamePasswordRealm { final FileUserPasswdStore userPasswdStore; final FileUserRolesStore userRolesStore; - public FileRealm(RealmConfig config, FileUserPasswdStore userPasswdStore, FileUserRolesStore userRolesStore) { + public FileRealm(RealmConfig config, ResourceWatcherService watcherService) { + this(config, new FileUserPasswdStore(config, watcherService), new FileUserRolesStore(config, watcherService)); + } + + // pkg private for testing + FileRealm(RealmConfig config, FileUserPasswdStore userPasswdStore, FileUserRolesStore userRolesStore) { super(TYPE, config); Listener listener = new Listener(); this.userPasswdStore = userPasswdStore; @@ -76,31 +76,4 @@ public class FileRealm extends CachingUsernamePasswordRealm { expireAll(); } } - - public static class Factory extends UsernamePasswordRealm.Factory { - - private final Settings settings; - private final Environment env; - private final ResourceWatcherService watcherService; - - @Inject - public Factory(Settings settings, Environment env, ResourceWatcherService watcherService) { - super(TYPE, true); - this.settings = settings; - this.env = env; - this.watcherService = watcherService; - } - - @Override - public FileRealm create(RealmConfig config) { - return new FileRealm(config, new FileUserPasswdStore(config, watcherService), - new FileUserRolesStore(config, watcherService)); - } - - @Override - public FileRealm createDefault(String name) { - RealmConfig config = new RealmConfig(name, Settings.EMPTY, settings, env); - return create(config); - } - } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealm.java index cc1a739f36d..4f0fc570592 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealm.java @@ -5,19 +5,15 @@ */ package org.elasticsearch.xpack.security.authc.ldap; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.common.inject.Inject; +import java.util.Map; + import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.rest.RestController; +import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.ldap.support.AbstractLdapRealm; import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory; import org.elasticsearch.xpack.security.authc.support.DnRoleMapper; import org.elasticsearch.xpack.security.ssl.ClientSSLService; -import org.elasticsearch.watcher.ResourceWatcherService; - -import java.io.IOException; -import java.util.Map; /** * Authenticates username/password tokens against ldap, locates groups and maps them to roles. @@ -26,55 +22,36 @@ public class LdapRealm extends AbstractLdapRealm { public static final String TYPE = "ldap"; - public LdapRealm(RealmConfig config, SessionFactory ldap, DnRoleMapper roleMapper) { - super(TYPE, config, ldap, roleMapper); + public LdapRealm(RealmConfig config, ResourceWatcherService watcherService, ClientSSLService clientSSLService) { + this(config, sessionFactory(config, clientSSLService), new DnRoleMapper(TYPE, config, watcherService, null)); + } + + // pkg private for testing + LdapRealm(RealmConfig config, SessionFactory sessionFactory, DnRoleMapper roleMapper) { + super(TYPE, config, sessionFactory, roleMapper); + } + + static SessionFactory sessionFactory(RealmConfig config, ClientSSLService clientSSLService) { + Settings searchSettings = userSearchSettings(config); + if (!searchSettings.names().isEmpty()) { + if (config.settings().getAsArray(LdapSessionFactory.USER_DN_TEMPLATES_SETTING).length > 0) { + throw new IllegalArgumentException("settings were found for both user search and user template modes of operation. " + + "Please remove the settings for the mode you do not wish to use. For more details refer to the ldap " + + "authentication section of the X-Pack guide."); + } + return new LdapUserSearchSessionFactory(config, clientSSLService).init(); + } + return new LdapSessionFactory(config, clientSSLService).init(); + } + + static Settings userSearchSettings(RealmConfig config) { + return config.settings().getAsSettings("user_search"); } @Override public Map usageStats() { Map stats = super.usageStats(); - stats.put("user_search", Factory.userSearchSettings(config).isEmpty() == false); + stats.put("user_search", userSearchSettings(config).isEmpty() == false); return stats; } - - public static class Factory extends AbstractLdapRealm.Factory { - - private final ResourceWatcherService watcherService; - private final ClientSSLService clientSSLService; - - @Inject - public Factory(ResourceWatcherService watcherService, ClientSSLService clientSSLService) { - super(TYPE); - this.watcherService = watcherService; - this.clientSSLService = clientSSLService; - } - - @Override - public LdapRealm create(RealmConfig config) { - try { - SessionFactory sessionFactory = sessionFactory(config, clientSSLService); - DnRoleMapper roleMapper = new DnRoleMapper(TYPE, config, watcherService, null); - return new LdapRealm(config, sessionFactory, roleMapper); - } catch (IOException e) { - throw new ElasticsearchException("failed to create realm [{}/{}]", e, LdapRealm.TYPE, config.name()); - } - } - - static SessionFactory sessionFactory(RealmConfig config, ClientSSLService clientSSLService) throws IOException { - Settings searchSettings = userSearchSettings(config); - if (!searchSettings.names().isEmpty()) { - if (config.settings().getAsArray(LdapSessionFactory.USER_DN_TEMPLATES_SETTING).length > 0) { - throw new IllegalArgumentException("settings were found for both user search and user template modes of operation. " + - "Please remove the settings for the mode you do not wish to use. For more details refer to the ldap " + - "authentication section of the X-Pack guide."); - } - return new LdapUserSearchSessionFactory(config, clientSSLService).init(); - } - return new LdapSessionFactory(config, clientSSLService).init(); - } - - static Settings userSearchSettings(RealmConfig config) { - return config.settings().getAsSettings("user_search"); - } - } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/support/AbstractLdapRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/support/AbstractLdapRealm.java index 68ef7ea0e7f..4c542f44e8b 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/support/AbstractLdapRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/support/AbstractLdapRealm.java @@ -5,18 +5,16 @@ */ package org.elasticsearch.xpack.security.authc.ldap.support; -import org.elasticsearch.rest.RestController; -import org.elasticsearch.xpack.security.user.User; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm; import org.elasticsearch.xpack.security.authc.support.DnRoleMapper; import org.elasticsearch.xpack.security.authc.support.RefreshListener; -import org.elasticsearch.xpack.security.authc.support.UsernamePasswordRealm; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; - -import java.util.List; -import java.util.Map; -import java.util.Set; +import org.elasticsearch.xpack.security.user.User; /** * Supporting class for LDAP realms @@ -100,21 +98,4 @@ public abstract class AbstractLdapRealm extends CachingUsernamePasswordRealm { expireAll(); } } - - public abstract static class Factory extends UsernamePasswordRealm.Factory { - - public Factory(String type) { - super(type, false); - } - - /** - * LDAP realms require minimum settings (e.g. URL), therefore they'll never create a default. - * - * @return {@code null} always - */ - @Override - public final R createDefault(String name) { - return null; - } - } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java index 9d129799612..d128d25f092 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java @@ -38,7 +38,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class PkiRealm extends Realm { +public class PkiRealm extends Realm { public static final String PKI_CERT_HEADER_NAME = "__SECURITY_CLIENT_CERTIFICATE"; public static final String TYPE = "pki"; @@ -51,7 +51,13 @@ public class PkiRealm extends Realm { private final Pattern principalPattern; private final DnRoleMapper roleMapper; - public PkiRealm(RealmConfig config, DnRoleMapper roleMapper) { + + public PkiRealm(RealmConfig config, ResourceWatcherService watcherService) { + this(config, new DnRoleMapper(TYPE, config, watcherService, null)); + } + + // pkg private for testing + PkiRealm(RealmConfig config, DnRoleMapper roleMapper) { super(TYPE, config); this.trustManagers = trustManagers(config.settings(), config.env()); this.principalPattern = Pattern.compile(config.settings().get("username_pattern", DEFAULT_USERNAME_PATTERN), @@ -71,7 +77,8 @@ public class PkiRealm extends Realm { } @Override - public User authenticate(X509AuthenticationToken token) { + public User authenticate(AuthenticationToken authToken) { + X509AuthenticationToken token = (X509AuthenticationToken)authToken; if (!isCertificateChainTrusted(trustManagers, token, logger)) { return null; } @@ -222,26 +229,4 @@ public class PkiRealm extends Realm { logger.error("PKI realm [{}] is enabled but cannot be used as neither HTTP or Transport have both SSL and client authentication " + "enabled", config.name()); } - - public static class Factory extends Realm.Factory { - - private final ResourceWatcherService watcherService; - - @Inject - public Factory(ResourceWatcherService watcherService) { - super(TYPE, false); - this.watcherService = watcherService; - } - - @Override - public PkiRealm create(RealmConfig config) { - DnRoleMapper roleMapper = new DnRoleMapper(TYPE, config, watcherService, null); - return new PkiRealm(config, roleMapper); - } - - @Override - public PkiRealm createDefault(String name) { - return null; - } - } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java index 5cd1e69288d..54e5b59b1d6 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java @@ -10,6 +10,8 @@ import org.elasticsearch.common.cache.Cache; import org.elasticsearch.common.cache.CacheBuilder; import org.elasticsearch.common.cache.CacheLoader; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.xpack.security.authc.Authentication; +import org.elasticsearch.xpack.security.authc.AuthenticationToken; import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.support.Exceptions; import org.elasticsearch.xpack.security.user.User; @@ -63,11 +65,12 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm * against a hash also stored in the cache. Otherwise the subclass authenticates the user via * doAuthenticate * - * @param token The authentication token + * @param authToken The authentication token * @return an authenticated user with roles */ @Override - public final User authenticate(final UsernamePasswordToken token) { + public final User authenticate(AuthenticationToken authToken) { + UsernamePasswordToken token = (UsernamePasswordToken)authToken; if (cache == null) { return doAuthenticate(token); } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java index 24d08517c26..1bac5a68aab 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java @@ -16,7 +16,7 @@ import java.util.Locale; /** * */ -public abstract class UsernamePasswordRealm extends Realm { +public abstract class UsernamePasswordRealm extends Realm { public UsernamePasswordRealm(String type, RealmConfig config) { super(type, config); @@ -31,13 +31,6 @@ public abstract class UsernamePasswordRealm extends Realm return token instanceof UsernamePasswordToken; } - public abstract static class Factory extends Realm.Factory { - - protected Factory(String type, boolean internal) { - super(type, internal); - } - } - public enum UserbaseSize { TINY, diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java new file mode 100644 index 00000000000..a04880ebb12 --- /dev/null +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java @@ -0,0 +1,33 @@ +/* + * 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.xpack.security; + +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.test.ESTestCase; +import org.junit.Before; + +public class SecurityTests extends ESTestCase { + + private Environment env; + + @Before + public void setupEnv() { + Settings settings = Settings.builder() + .put("path.home", createTempDir()).build(); + env = new Environment(settings); + } + + public void testCustomRealmExtension() throws Exception { + Security security = new Security(Settings.EMPTY, env); + + //security.createComponents(null, null, null, ) + } + + public void testCustomRealmExtensionConflict() throws Exception { + + } +} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationModuleTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationModuleTests.java deleted file mode 100644 index aedd3a25917..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationModuleTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.xpack.security.authc; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; -import org.elasticsearch.xpack.security.authc.file.FileRealm; -import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; -import org.elasticsearch.xpack.security.authc.pki.PkiRealm; -import org.elasticsearch.test.ESTestCase; - -import static org.hamcrest.Matchers.containsString; - -/** - * Unit tests for the AuthenticationModule - */ -public class AuthenticationModuleTests extends ESTestCase { - public void testAddingReservedRealmType() { - Settings settings = Settings.EMPTY; - AuthenticationModule module = new AuthenticationModule(settings); - try { - module.addCustomRealm(randomFrom(PkiRealm.TYPE, LdapRealm.TYPE, ActiveDirectoryRealm.TYPE, FileRealm.TYPE), - randomFrom(PkiRealm.Factory.class, LdapRealm.Factory.class, ActiveDirectoryRealm.Factory.class, - FileRealm.Factory.class)); - fail("overriding a built in realm type is not allowed!"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("cannot redefine")); - } - } - - public void testAddingNullOrEmptyType() { - Settings settings = Settings.EMPTY; - AuthenticationModule module = new AuthenticationModule(settings); - try { - module.addCustomRealm(randomBoolean() ? null : "", - randomFrom(PkiRealm.Factory.class, LdapRealm.Factory.class, ActiveDirectoryRealm.Factory.class, - FileRealm.Factory.class)); - fail("type must not be null"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("null or empty")); - } - } - - public void testAddingNullFactory() { - Settings settings = Settings.EMPTY; - AuthenticationModule module = new AuthenticationModule(settings); - try { - module.addCustomRealm(randomAsciiOfLength(7), null); - fail("factory must not be null"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("null")); - } - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java index f58558aec77..2102a461789 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java @@ -33,9 +33,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -/** - * - */ public class RealmsTests extends ESTestCase { private Map factories; private SecurityLicenseState securityLicenseState; @@ -44,11 +41,11 @@ public class RealmsTests extends ESTestCase { @Before public void init() throws Exception { factories = new HashMap<>(); - factories.put(FileRealm.TYPE, new DummyRealm.Factory(FileRealm.TYPE, true)); - factories.put(NativeRealm.TYPE, new DummyRealm.Factory(NativeRealm.TYPE, true)); + factories.put(FileRealm.TYPE, config -> new DummyRealm(FileRealm.TYPE, config)); + factories.put(NativeRealm.TYPE, config -> new DummyRealm(NativeRealm.TYPE, config)); for (int i = 0; i < randomIntBetween(1, 5); i++) { - DummyRealm.Factory factory = new DummyRealm.Factory("type_" + i, rarely()); - factories.put("type_" + i, factory); + String name = "type_" + i; + factories.put(name, config -> new DummyRealm(name, config)); } securityLicenseState = mock(SecurityLicenseState.class); reservedRealm = mock(ReservedRealm.class); @@ -195,7 +192,7 @@ public class RealmsTests extends ESTestCase { } public void testUnlicensedWithInternalRealms() throws Exception { - factories.put(LdapRealm.TYPE, new DummyRealm.Factory(LdapRealm.TYPE, false)); + factories.put(LdapRealm.TYPE, config -> new DummyRealm(LdapRealm.TYPE, config)); assertThat(factories.get("type_0"), notNullValue()); Settings.Builder builder = Settings.builder() .put("path.home", createTempDir()) @@ -252,7 +249,7 @@ public class RealmsTests extends ESTestCase { } public void testUnlicensedWithNativeRealms() throws Exception { - factories.put(LdapRealm.TYPE, new DummyRealm.Factory(LdapRealm.TYPE, false)); + factories.put(LdapRealm.TYPE, config -> new DummyRealm(LdapRealm.TYPE, config)); final String type = randomFrom(FileRealm.TYPE, NativeRealm.TYPE); Settings.Builder builder = Settings.builder() .put("path.home", createTempDir()) @@ -385,26 +382,5 @@ public class RealmsTests extends ESTestCase { public boolean userLookupSupported() { return false; } - - static class Factory extends Realm.Factory { - - public Factory(String type, boolean internal) { - super(type, internal); - } - - @Override - public DummyRealm create(RealmConfig config) { - return new DummyRealm(type(), config); - } - - @Override - public DummyRealm createDefault(String name) { - if (type().equals(NativeRealm.TYPE) || type().equals(FileRealm.TYPE)) { - return new DummyRealm(type(), new RealmConfig(name, Settings.EMPTY, - Settings.builder().put("path.home", createTempDir()).build())); - } - return null; - } - } } } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java index 56588941cfe..1f90bc69610 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java @@ -164,7 +164,7 @@ public class LdapRealmTests extends LdapTestCase { .put(HOSTNAME_VERIFICATION_SETTING, false) .build(); RealmConfig config = new RealmConfig("test-ldap-realm", settings, globalSettings); - SessionFactory sessionFactory = LdapRealm.Factory.sessionFactory(config, null); + SessionFactory sessionFactory = LdapRealm.sessionFactory(config, null); assertThat(sessionFactory, is(instanceOf(LdapSessionFactory.class))); } @@ -180,7 +180,7 @@ public class LdapRealmTests extends LdapTestCase { .put(HOSTNAME_VERIFICATION_SETTING, false) .build(); RealmConfig config = new RealmConfig("test-ldap-realm-user-search", settings, globalSettings); - SessionFactory sessionFactory = LdapRealm.Factory.sessionFactory(config, null); + SessionFactory sessionFactory = LdapRealm.sessionFactory(config, null); try { assertThat(sessionFactory, is(instanceOf(LdapUserSearchSessionFactory.class))); } finally { @@ -199,7 +199,7 @@ public class LdapRealmTests extends LdapTestCase { .build(); RealmConfig config = new RealmConfig("test-ldap-realm-user-search", settings, globalSettings); try { - LdapRealm.Factory.sessionFactory(config, null); + LdapRealm.sessionFactory(config, null); fail("an exception should have been thrown because both user template and user search settings were specified"); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("settings were found for both user search and user template")); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealmTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealmTests.java index 09b1e12852b..bd45c406c46 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealmTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealmTests.java @@ -142,7 +142,7 @@ public class CachingUsernamePasswordRealmTests extends ESTestCase { } public void testAuthenticateContract() throws Exception { - Realm realm = new FailingAuthenticationRealm(Settings.EMPTY, globalSettings); + Realm realm = new FailingAuthenticationRealm(Settings.EMPTY, globalSettings); User user = realm.authenticate(new UsernamePasswordToken("user", SecuredStringTests.build("pass"))); assertThat(user , nullValue()); @@ -152,7 +152,7 @@ public class CachingUsernamePasswordRealmTests extends ESTestCase { } public void testLookupContract() throws Exception { - Realm realm = new FailingAuthenticationRealm(Settings.EMPTY, globalSettings); + Realm realm = new FailingAuthenticationRealm(Settings.EMPTY, globalSettings); User user = realm.lookupUser("user"); assertThat(user , nullValue()); diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 63322c8aba3..1203ccb16a1 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -192,8 +192,8 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin { components.add(internalClient); components.addAll(licensing.createComponents(clusterService, getClock(), env, resourceWatcherService, - security.getSecurityLicenseState())); - components.addAll(security.createComponents(resourceWatcherService)); + security.getSecurityLicenseState())); + components.addAll(security.createComponents(internalClient, threadPool, resourceWatcherService, extensionsService.getExtensions())); // watcher http stuff Map httpAuthFactories = new HashMap<>(); diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/extensions/XPackExtension.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/extensions/XPackExtension.java index 11459645663..be819449dc7 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/extensions/XPackExtension.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/extensions/XPackExtension.java @@ -7,8 +7,12 @@ package org.elasticsearch.xpack.extensions; import java.util.Collection; import java.util.Collections; +import java.util.Map; +import org.elasticsearch.watcher.ResourceWatcherService; +import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler; import org.elasticsearch.xpack.security.authc.AuthenticationModule; +import org.elasticsearch.xpack.security.authc.Realm; /** @@ -36,4 +40,16 @@ public abstract class XPackExtension { public Collection getRestHeaders() { return Collections.emptyList(); } + + + /** + * Returns authentication realm implementations added by this extension. + * + * The key of the returned {@link Map} is the type name of the realm, and the value + * is a {@link org.elasticsearch.xpack.security.authc.Realm.Factory} which will construct + * that realm for use in authentication when that realm type is configured. + */ + public Map getRealms() { + return Collections.emptyMap(); + } }