Internal: Remove guice from authentication and authorization services
This change removes guice from most of the rest of security. It also converts the last use of onModule in xpack extensions to a pull based extension. Original commit: elastic/x-pack-elasticsearch@9de072550e
This commit is contained in:
parent
4b4e7158eb
commit
f05005f667
|
@ -7,7 +7,7 @@ package org.elasticsearch.example;
|
||||||
|
|
||||||
import org.elasticsearch.example.realm.CustomAuthenticationFailureHandler;
|
import org.elasticsearch.example.realm.CustomAuthenticationFailureHandler;
|
||||||
import org.elasticsearch.example.realm.CustomRealm;
|
import org.elasticsearch.example.realm.CustomRealm;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationModule;
|
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.extensions.XPackExtension;
|
import org.elasticsearch.xpack.extensions.XPackExtension;
|
||||||
import org.elasticsearch.xpack.security.authc.Realm;
|
import org.elasticsearch.xpack.security.authc.Realm;
|
||||||
|
|
||||||
|
@ -38,15 +38,16 @@ public class ExampleRealmExtension extends XPackExtension {
|
||||||
return "a very basic implementation of a custom realm to validate it works";
|
return "a very basic implementation of a custom realm to validate it works";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(AuthenticationModule authenticationModule) {
|
|
||||||
authenticationModule.setAuthenticationFailureHandler(CustomAuthenticationFailureHandler.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Realm.Factory> getRealms() {
|
public Map<String, Realm.Factory> getRealms() {
|
||||||
return Collections.singletonMap(CustomRealm.TYPE, CustomRealm::new);
|
return Collections.singletonMap(CustomRealm.TYPE, CustomRealm::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticationFailureHandler getAuthenticationFailureHandler() {
|
||||||
|
return new CustomAuthenticationFailureHandler();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getRestHeaders() {
|
public Collection<String> getRestHeaders() {
|
||||||
return Arrays.asList(CustomRealm.USER_HEADER, CustomRealm.PW_HEADER);
|
return Arrays.asList(CustomRealm.USER_HEADER, CustomRealm.PW_HEADER);
|
||||||
|
|
|
@ -74,7 +74,8 @@ import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
||||||
import org.elasticsearch.xpack.security.audit.index.IndexNameResolver;
|
import org.elasticsearch.xpack.security.audit.index.IndexNameResolver;
|
||||||
import org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail;
|
import org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationModule;
|
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
||||||
|
import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
||||||
import org.elasticsearch.xpack.security.authc.Realm;
|
import org.elasticsearch.xpack.security.authc.Realm;
|
||||||
import org.elasticsearch.xpack.security.authc.Realms;
|
import org.elasticsearch.xpack.security.authc.Realms;
|
||||||
|
@ -88,13 +89,14 @@ import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory;
|
||||||
import org.elasticsearch.xpack.security.authc.pki.PkiRealm;
|
import org.elasticsearch.xpack.security.authc.pki.PkiRealm;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.xpack.security.authz.AuthorizationModule;
|
|
||||||
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
||||||
import org.elasticsearch.xpack.security.authz.accesscontrol.SetSecurityUserProcessor;
|
import org.elasticsearch.xpack.security.authz.accesscontrol.SetSecurityUserProcessor;
|
||||||
import org.elasticsearch.xpack.security.authz.accesscontrol.OptOutQueryCache;
|
import org.elasticsearch.xpack.security.authz.accesscontrol.OptOutQueryCache;
|
||||||
import org.elasticsearch.xpack.security.authz.accesscontrol.SecurityIndexSearcherWrapper;
|
import org.elasticsearch.xpack.security.authz.accesscontrol.SecurityIndexSearcherWrapper;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||||
import org.elasticsearch.xpack.security.authz.store.FileRolesStore;
|
import org.elasticsearch.xpack.security.authz.store.FileRolesStore;
|
||||||
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
|
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.ReservedRolesStore;
|
||||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||||
import org.elasticsearch.xpack.security.rest.SecurityRestModule;
|
import org.elasticsearch.xpack.security.rest.SecurityRestModule;
|
||||||
import org.elasticsearch.xpack.security.rest.action.RestAuthenticateAction;
|
import org.elasticsearch.xpack.security.rest.action.RestAuthenticateAction;
|
||||||
|
@ -183,7 +185,6 @@ public class Security implements ActionPlugin, IngestPlugin {
|
||||||
if (enabled == false) {
|
if (enabled == false) {
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
modules.add(new SecurityModule(settings));
|
|
||||||
modules.add(new SecurityTransportModule(settings));
|
modules.add(new SecurityTransportModule(settings));
|
||||||
modules.add(b -> {
|
modules.add(b -> {
|
||||||
// for transport client we still must inject these ssl classes with guice
|
// for transport client we still must inject these ssl classes with guice
|
||||||
|
@ -194,16 +195,16 @@ public class Security implements ActionPlugin, IngestPlugin {
|
||||||
|
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
modules.add(b -> XPackPlugin.bindFeatureSet(b, SecurityFeatureSet.class));
|
||||||
|
|
||||||
modules.add(new AuthenticationModule(settings));
|
|
||||||
modules.add(new AuthorizationModule(settings));
|
|
||||||
if (enabled == false) {
|
if (enabled == false) {
|
||||||
modules.add(b -> {
|
modules.add(b -> {
|
||||||
b.bind(CryptoService.class).toProvider(Providers.of(null));
|
b.bind(CryptoService.class).toProvider(Providers.of(null));
|
||||||
|
b.bind(Realms.class).toProvider(Providers.of(null)); // for SecurityFeatureSet
|
||||||
|
b.bind(CompositeRolesStore.class).toProvider(Providers.of(null)); // for SecurityFeatureSet
|
||||||
b.bind(AuditTrailService.class)
|
b.bind(AuditTrailService.class)
|
||||||
.toInstance(new AuditTrailService(settings, Collections.emptyList(), securityLicenseState));
|
.toInstance(new AuditTrailService(settings, Collections.emptyList(), securityLicenseState));
|
||||||
});
|
});
|
||||||
modules.add(new SecurityModule(settings));
|
|
||||||
modules.add(new SecurityTransportModule(settings));
|
modules.add(new SecurityTransportModule(settings));
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
@ -216,32 +217,20 @@ public class Security implements ActionPlugin, IngestPlugin {
|
||||||
if (auditingEnabled(settings)) {
|
if (auditingEnabled(settings)) {
|
||||||
b.bind(AuditTrail.class).to(AuditTrailService.class); // interface used by some actions...
|
b.bind(AuditTrail.class).to(AuditTrailService.class); // interface used by some actions...
|
||||||
}
|
}
|
||||||
if (indexAuditLoggingEnabled(settings) == false) {
|
|
||||||
// TODO: remove this once we can construct SecurityLifecycleService without guice
|
|
||||||
b.bind(IndexAuditTrail.class).toProvider(Providers.of(null));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
modules.add(new SecurityModule(settings));
|
|
||||||
modules.add(new SecurityRestModule(settings));
|
modules.add(new SecurityRestModule(settings));
|
||||||
modules.add(new SecurityActionModule(settings));
|
modules.add(new SecurityActionModule(settings));
|
||||||
modules.add(new SecurityTransportModule(settings));
|
modules.add(new SecurityTransportModule(settings));
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Class<? extends LifecycleComponent>> nodeServices() {
|
|
||||||
if (enabled == false || transportClientMode == true) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
List<Class<? extends LifecycleComponent>> list = new ArrayList<>();
|
|
||||||
list.add(FileRolesStore.class);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Object> createComponents(InternalClient client, ThreadPool threadPool, ClusterService clusterService,
|
public Collection<Object> createComponents(InternalClient client, ThreadPool threadPool, ClusterService clusterService,
|
||||||
ResourceWatcherService resourceWatcherService, List<XPackExtension> extensions) {
|
ResourceWatcherService resourceWatcherService, List<XPackExtension> extensions) {
|
||||||
if (enabled == false) {
|
if (enabled == false) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
AnonymousUser.initialize(settings); // TODO: this is sketchy...testing is difficult b/c it is static....
|
||||||
|
|
||||||
List<Object> components = new ArrayList<>();
|
List<Object> components = new ArrayList<>();
|
||||||
final SecurityContext securityContext = new SecurityContext(settings, threadPool, cryptoService);
|
final SecurityContext securityContext = new SecurityContext(settings, threadPool, cryptoService);
|
||||||
components.add(securityContext);
|
components.add(securityContext);
|
||||||
|
@ -275,6 +264,7 @@ public class Security implements ActionPlugin, IngestPlugin {
|
||||||
components.add(realms);
|
components.add(realms);
|
||||||
|
|
||||||
// audit trails construction
|
// audit trails construction
|
||||||
|
IndexAuditTrail indexAuditTrail = null;
|
||||||
Set<AuditTrail> auditTrails = new LinkedHashSet<>();
|
Set<AuditTrail> auditTrails = new LinkedHashSet<>();
|
||||||
if (AUDIT_ENABLED_SETTING.get(settings)) {
|
if (AUDIT_ENABLED_SETTING.get(settings)) {
|
||||||
List<String> outputs = AUDIT_OUTPUTS_SETTING.get(settings);
|
List<String> outputs = AUDIT_OUTPUTS_SETTING.get(settings);
|
||||||
|
@ -289,16 +279,54 @@ public class Security implements ActionPlugin, IngestPlugin {
|
||||||
auditTrails.add(new LoggingAuditTrail(settings, clusterService, threadPool));
|
auditTrails.add(new LoggingAuditTrail(settings, clusterService, threadPool));
|
||||||
break;
|
break;
|
||||||
case IndexAuditTrail.NAME:
|
case IndexAuditTrail.NAME:
|
||||||
IndexAuditTrail indexAuditTrail = new IndexAuditTrail(settings, client, threadPool, clusterService);
|
indexAuditTrail = new IndexAuditTrail(settings, client, threadPool, clusterService);
|
||||||
auditTrails.add(indexAuditTrail);
|
auditTrails.add(indexAuditTrail);
|
||||||
components.add(indexAuditTrail); // SecurityLifecycleService needs this....
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown audit trail output [" + output + "]");
|
throw new IllegalArgumentException("Unknown audit trail output [" + output + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
components.add(new AuditTrailService(settings, auditTrails.stream().collect(Collectors.toList()), securityLicenseState));
|
final AuditTrailService auditTrailService =
|
||||||
|
new AuditTrailService(settings, auditTrails.stream().collect(Collectors.toList()), securityLicenseState);
|
||||||
|
components.add(auditTrailService);
|
||||||
|
|
||||||
|
AuthenticationFailureHandler failureHandler = null;
|
||||||
|
String extensionName = null;
|
||||||
|
for (XPackExtension extension : extensions) {
|
||||||
|
AuthenticationFailureHandler extensionFailureHandler = extension.getAuthenticationFailureHandler();
|
||||||
|
if (extensionFailureHandler != null && failureHandler != null) {
|
||||||
|
throw new IllegalStateException("Extensions [" + extensionName +"] and [" + extension.name() + "] " +
|
||||||
|
"both set an authentication failure handler");
|
||||||
|
}
|
||||||
|
failureHandler = extensionFailureHandler;
|
||||||
|
extensionName = extension.name();
|
||||||
|
}
|
||||||
|
if (failureHandler == null) {
|
||||||
|
logger.debug("Using default authentication failure handler");
|
||||||
|
failureHandler = new DefaultAuthenticationFailureHandler();
|
||||||
|
} else {
|
||||||
|
logger.debug("Using authentication failure handler from extension [" + extensionName + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
final AuthenticationService authcService = new AuthenticationService(settings, realms, auditTrailService,
|
||||||
|
cryptoService, failureHandler, threadPool);
|
||||||
|
components.add(authcService);
|
||||||
|
|
||||||
|
final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService);
|
||||||
|
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, threadPool);
|
||||||
|
final ReservedRolesStore reservedRolesStore = new ReservedRolesStore(securityContext);
|
||||||
|
final CompositeRolesStore allRolesStore = new CompositeRolesStore(fileRolesStore, nativeRolesStore, reservedRolesStore);
|
||||||
|
final AuthorizationService authzService = new AuthorizationService(settings, allRolesStore, clusterService,
|
||||||
|
auditTrailService, failureHandler, threadPool);
|
||||||
|
components.add(fileRolesStore); // has lifecycle
|
||||||
|
components.add(nativeRolesStore); // used by roles actions
|
||||||
|
components.add(reservedRolesStore); // used by roles actions
|
||||||
|
components.add(allRolesStore); // for SecurityFeatureSet
|
||||||
|
components.add(authzService);
|
||||||
|
|
||||||
|
components.add(new SecurityLifecycleService(settings, clusterService, threadPool, indexAuditTrail,
|
||||||
|
nativeUsersStore, nativeRolesStore, client));
|
||||||
|
|
||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.elasticsearch.xpack.security.authc.Realm;
|
||||||
import org.elasticsearch.xpack.security.authc.Realms;
|
import org.elasticsearch.xpack.security.authc.Realms;
|
||||||
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
|
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
|
||||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||||
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
||||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||||
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
||||||
|
@ -43,7 +44,7 @@ public class SecurityFeatureSet implements XPackFeatureSet {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Realms realms;
|
private final Realms realms;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final RolesStore rolesStore;
|
private final CompositeRolesStore rolesStore;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final IPFilter ipFilter;
|
private final IPFilter ipFilter;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -52,8 +53,8 @@ public class SecurityFeatureSet implements XPackFeatureSet {
|
||||||
private final CryptoService cryptoService;
|
private final CryptoService cryptoService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SecurityFeatureSet(Settings settings, @Nullable SecurityLicenseState licenseState,
|
public SecurityFeatureSet(Settings settings, @Nullable SecurityLicenseState licenseState, @Nullable Realms realms,
|
||||||
@Nullable Realms realms, NamedWriteableRegistry namedWriteableRegistry, @Nullable RolesStore rolesStore,
|
NamedWriteableRegistry namedWriteableRegistry, @Nullable CompositeRolesStore rolesStore,
|
||||||
@Nullable IPFilter ipFilter, @Nullable AuditTrailService auditTrailService,
|
@Nullable IPFilter ipFilter, @Nullable AuditTrailService auditTrailService,
|
||||||
@Nullable CryptoService cryptoService) {
|
@Nullable CryptoService cryptoService) {
|
||||||
this.enabled = Security.enabled(settings);
|
this.enabled = Security.enabled(settings);
|
||||||
|
|
|
@ -6,18 +6,17 @@
|
||||||
package org.elasticsearch.xpack.security;
|
package org.elasticsearch.xpack.security;
|
||||||
|
|
||||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||||
import org.elasticsearch.cluster.service.ClusterService;
|
|
||||||
import org.elasticsearch.cluster.ClusterStateListener;
|
import org.elasticsearch.cluster.ClusterStateListener;
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.component.LifecycleListener;
|
import org.elasticsearch.common.component.LifecycleListener;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.inject.internal.Nullable;
|
import org.elasticsearch.common.inject.internal.Nullable;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
||||||
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
|
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
|
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to provide a lifecycle for services that is based on the cluster's state
|
* This class is used to provide a lifecycle for services that is based on the cluster's state
|
||||||
|
@ -38,7 +37,6 @@ public class SecurityLifecycleService extends AbstractComponent implements Clust
|
||||||
private final NativeUsersStore nativeUserStore;
|
private final NativeUsersStore nativeUserStore;
|
||||||
private final NativeRolesStore nativeRolesStore;
|
private final NativeRolesStore nativeRolesStore;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public SecurityLifecycleService(Settings settings, ClusterService clusterService, ThreadPool threadPool,
|
public SecurityLifecycleService(Settings settings, ClusterService clusterService, ThreadPool threadPool,
|
||||||
@Nullable IndexAuditTrail indexAuditTrail, NativeUsersStore nativeUserStore,
|
@Nullable IndexAuditTrail indexAuditTrail, NativeUsersStore nativeUserStore,
|
||||||
NativeRolesStore nativeRolesStore, InternalClient client) {
|
NativeRolesStore nativeRolesStore, InternalClient client) {
|
||||||
|
|
|
@ -1,34 +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;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
|
||||||
import org.elasticsearch.xpack.security.support.AbstractSecurityModule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SecurityModule extends AbstractSecurityModule {
|
|
||||||
|
|
||||||
public SecurityModule(Settings settings) {
|
|
||||||
super(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(boolean clientMode) {
|
|
||||||
if (clientMode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
XPackPlugin.bindFeatureSet(binder(), SecurityFeatureSet.class);
|
|
||||||
|
|
||||||
if (securityEnabled) {
|
|
||||||
bind(SecurityLifecycleService.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,46 +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.inject.util.Providers;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.xpack.security.support.AbstractSecurityModule;
|
|
||||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AuthenticationModule extends AbstractSecurityModule.Node {
|
|
||||||
|
|
||||||
private Class<? extends AuthenticationFailureHandler> authcFailureHandler = null;
|
|
||||||
|
|
||||||
public AuthenticationModule(Settings settings) {
|
|
||||||
super(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configureNode() {
|
|
||||||
if (!securityEnabled) {
|
|
||||||
bind(Realms.class).toProvider(Providers.of(null));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnonymousUser.initialize(settings);
|
|
||||||
if (authcFailureHandler == null) {
|
|
||||||
bind(AuthenticationFailureHandler.class).to(DefaultAuthenticationFailureHandler.class).asEagerSingleton();
|
|
||||||
} else {
|
|
||||||
bind(AuthenticationFailureHandler.class).to(authcFailureHandler).asEagerSingleton();
|
|
||||||
}
|
|
||||||
bind(AuthenticationService.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the {@link AuthenticationFailureHandler} to the specified implementation
|
|
||||||
*/
|
|
||||||
public void setAuthenticationFailureHandler(Class<? extends AuthenticationFailureHandler> clazz) {
|
|
||||||
this.authcFailureHandler = clazz;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,16 +5,17 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authc;
|
package org.elasticsearch.xpack.security.authc;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchSecurityException;
|
import org.elasticsearch.ElasticsearchSecurityException;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Setting.Property;
|
import org.elasticsearch.common.settings.Setting.Property;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.rest.RestController;
|
|
||||||
import org.elasticsearch.node.Node;
|
import org.elasticsearch.node.Node;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
|
@ -26,9 +27,6 @@ import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportMessage;
|
import org.elasticsearch.transport.TransportMessage;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.Security.setting;
|
import static org.elasticsearch.xpack.security.Security.setting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +51,6 @@ public class AuthenticationService extends AbstractComponent {
|
||||||
private final boolean signUserHeader;
|
private final boolean signUserHeader;
|
||||||
private final boolean runAsEnabled;
|
private final boolean runAsEnabled;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public AuthenticationService(Settings settings, Realms realms, AuditTrailService auditTrail, CryptoService cryptoService,
|
public AuthenticationService(Settings settings, Realms realms, AuditTrailService auditTrail, CryptoService cryptoService,
|
||||||
AuthenticationFailureHandler failureHandler, ThreadPool threadPool) {
|
AuthenticationFailureHandler failureHandler, ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
|
|
@ -1,42 +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.authz;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.util.Providers;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.authz.store.FileRolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.authz.store.ReservedRolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.support.AbstractSecurityModule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module used to bind various classes necessary for authorization
|
|
||||||
*/
|
|
||||||
public class AuthorizationModule extends AbstractSecurityModule.Node {
|
|
||||||
|
|
||||||
public AuthorizationModule(Settings settings) {
|
|
||||||
super(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configureNode() {
|
|
||||||
if (securityEnabled == false) {
|
|
||||||
bind(RolesStore.class).toProvider(Providers.of(null));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First the file and native roles stores must be bound...
|
|
||||||
bind(ReservedRolesStore.class).asEagerSingleton();
|
|
||||||
bind(FileRolesStore.class).asEagerSingleton();
|
|
||||||
bind(NativeRolesStore.class).asEagerSingleton();
|
|
||||||
// Then the composite roles store (which combines both) can be bound
|
|
||||||
bind(RolesStore.class).to(CompositeRolesStore.class).asEagerSingleton();
|
|
||||||
bind(AuthorizationService.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,6 +5,13 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authz;
|
package org.elasticsearch.xpack.security.authz;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchSecurityException;
|
import org.elasticsearch.ElasticsearchSecurityException;
|
||||||
import org.elasticsearch.action.CompositeIndicesRequest;
|
import org.elasticsearch.action.CompositeIndicesRequest;
|
||||||
import org.elasticsearch.action.IndicesRequest;
|
import org.elasticsearch.action.IndicesRequest;
|
||||||
|
@ -12,28 +19,24 @@ import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||||
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
||||||
import org.elasticsearch.action.search.ClearScrollAction;
|
import org.elasticsearch.action.search.ClearScrollAction;
|
||||||
import org.elasticsearch.action.search.SearchScrollAction;
|
import org.elasticsearch.action.search.SearchScrollAction;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
|
||||||
import org.elasticsearch.cluster.service.ClusterService;
|
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.metadata.AliasOrIndex;
|
import org.elasticsearch.cluster.metadata.AliasOrIndex;
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Setting.Property;
|
import org.elasticsearch.common.settings.Setting.Property;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.common.util.set.Sets;
|
import org.elasticsearch.common.util.set.Sets;
|
||||||
import org.elasticsearch.search.action.SearchTransportService;
|
import org.elasticsearch.search.action.SearchTransportService;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.transport.TransportRequest;
|
||||||
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication;
|
|
||||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
|
||||||
import org.elasticsearch.xpack.security.user.SystemUser;
|
|
||||||
import org.elasticsearch.xpack.security.user.User;
|
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||||
|
import org.elasticsearch.xpack.security.authc.Authentication;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.security.authz.accesscontrol.IndicesAccessControl;
|
import org.elasticsearch.xpack.security.authz.accesscontrol.IndicesAccessControl;
|
||||||
import org.elasticsearch.xpack.security.authz.indicesresolver.DefaultIndicesAndAliasesResolver;
|
import org.elasticsearch.xpack.security.authz.indicesresolver.DefaultIndicesAndAliasesResolver;
|
||||||
|
@ -45,16 +48,13 @@ import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.RunAsPermission;
|
import org.elasticsearch.xpack.security.authz.permission.RunAsPermission;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.IndexPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.IndexPrivilege;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||||
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
|
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||||
|
import org.elasticsearch.xpack.security.user.SystemUser;
|
||||||
|
import org.elasticsearch.xpack.security.user.User;
|
||||||
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
|
||||||
import org.elasticsearch.transport.TransportRequest;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.Security.setting;
|
import static org.elasticsearch.xpack.security.Security.setting;
|
||||||
import static org.elasticsearch.xpack.security.support.Exceptions.authorizationError;
|
import static org.elasticsearch.xpack.security.support.Exceptions.authorizationError;
|
||||||
|
@ -72,23 +72,22 @@ public class AuthorizationService extends AbstractComponent {
|
||||||
private static final Predicate<String> MONITOR_INDEX_PREDICATE = IndexPrivilege.MONITOR.predicate();
|
private static final Predicate<String> MONITOR_INDEX_PREDICATE = IndexPrivilege.MONITOR.predicate();
|
||||||
|
|
||||||
private final ClusterService clusterService;
|
private final ClusterService clusterService;
|
||||||
private final RolesStore rolesStore;
|
private final CompositeRolesStore rolesStore;
|
||||||
private final AuditTrail auditTrail;
|
private final AuditTrailService auditTrail;
|
||||||
private final IndicesAndAliasesResolver[] indicesAndAliasesResolvers;
|
private final IndicesAndAliasesResolver[] indicesAndAliasesResolvers;
|
||||||
private final AuthenticationFailureHandler authcFailureHandler;
|
private final AuthenticationFailureHandler authcFailureHandler;
|
||||||
private final ThreadContext threadContext;
|
private final ThreadContext threadContext;
|
||||||
private final boolean anonymousAuthzExceptionEnabled;
|
private final boolean anonymousAuthzExceptionEnabled;
|
||||||
|
|
||||||
@Inject
|
public AuthorizationService(Settings settings, CompositeRolesStore rolesStore, ClusterService clusterService,
|
||||||
public AuthorizationService(Settings settings, RolesStore rolesStore, ClusterService clusterService,
|
|
||||||
AuditTrailService auditTrail, AuthenticationFailureHandler authcFailureHandler,
|
AuditTrailService auditTrail, AuthenticationFailureHandler authcFailureHandler,
|
||||||
ThreadPool threadPool, IndexNameExpressionResolver nameExpressionResolver) {
|
ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.rolesStore = rolesStore;
|
this.rolesStore = rolesStore;
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
this.auditTrail = auditTrail;
|
this.auditTrail = auditTrail;
|
||||||
this.indicesAndAliasesResolvers = new IndicesAndAliasesResolver[] {
|
this.indicesAndAliasesResolvers = new IndicesAndAliasesResolver[] {
|
||||||
new DefaultIndicesAndAliasesResolver(this, nameExpressionResolver)
|
new DefaultIndicesAndAliasesResolver(this, new IndexNameExpressionResolver(settings))
|
||||||
};
|
};
|
||||||
this.authcFailureHandler = authcFailureHandler;
|
this.authcFailureHandler = authcFailureHandler;
|
||||||
this.threadContext = threadPool.getThreadContext();
|
this.threadContext = threadPool.getThreadContext();
|
||||||
|
|
|
@ -21,7 +21,6 @@ public class CompositeRolesStore implements RolesStore {
|
||||||
private final NativeRolesStore nativeRolesStore;
|
private final NativeRolesStore nativeRolesStore;
|
||||||
private final ReservedRolesStore reservedRolesStore;
|
private final ReservedRolesStore reservedRolesStore;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public CompositeRolesStore(FileRolesStore fileRolesStore, NativeRolesStore nativeRolesStore, ReservedRolesStore reservedRolesStore) {
|
public CompositeRolesStore(FileRolesStore fileRolesStore, NativeRolesStore nativeRolesStore, ReservedRolesStore reservedRolesStore) {
|
||||||
this.fileRolesStore = fileRolesStore;
|
this.fileRolesStore = fileRolesStore;
|
||||||
this.nativeRolesStore = nativeRolesStore;
|
this.nativeRolesStore = nativeRolesStore;
|
||||||
|
|
|
@ -5,31 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authz.store;
|
package org.elasticsearch.xpack.security.authz.store;
|
||||||
|
|
||||||
import com.fasterxml.jackson.dataformat.yaml.snakeyaml.error.YAMLException;
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
|
||||||
import org.elasticsearch.common.settings.Setting.Property;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
|
|
||||||
import org.elasticsearch.env.Environment;
|
|
||||||
import org.elasticsearch.xpack.security.Security;
|
|
||||||
import org.elasticsearch.xpack.security.authc.support.RefreshListener;
|
|
||||||
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
|
||||||
import org.elasticsearch.xpack.security.authz.permission.IndicesPermission.Group;
|
|
||||||
import org.elasticsearch.xpack.security.authz.permission.Role;
|
|
||||||
import org.elasticsearch.xpack.security.support.NoOpLogger;
|
|
||||||
import org.elasticsearch.xpack.security.support.Validation;
|
|
||||||
import org.elasticsearch.watcher.FileChangesListener;
|
|
||||||
import org.elasticsearch.watcher.FileWatcher;
|
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -41,6 +16,30 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.yaml.snakeyaml.error.YAMLException;
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.settings.Setting;
|
||||||
|
import org.elasticsearch.common.settings.Setting.Property;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
|
||||||
|
import org.elasticsearch.env.Environment;
|
||||||
|
import org.elasticsearch.watcher.FileChangesListener;
|
||||||
|
import org.elasticsearch.watcher.FileWatcher;
|
||||||
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
|
import org.elasticsearch.xpack.security.Security;
|
||||||
|
import org.elasticsearch.xpack.security.authc.support.RefreshListener;
|
||||||
|
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
||||||
|
import org.elasticsearch.xpack.security.authz.permission.IndicesPermission.Group;
|
||||||
|
import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
|
import org.elasticsearch.xpack.security.support.NoOpLogger;
|
||||||
|
import org.elasticsearch.xpack.security.support.Validation;
|
||||||
|
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
import static java.util.Collections.emptySet;
|
import static java.util.Collections.emptySet;
|
||||||
import static java.util.Collections.unmodifiableMap;
|
import static java.util.Collections.unmodifiableMap;
|
||||||
|
@ -59,7 +58,6 @@ public class FileRolesStore extends AbstractLifecycleComponent implements RolesS
|
||||||
|
|
||||||
private volatile Map<String, Role> permissions;
|
private volatile Map<String, Role> permissions;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public FileRolesStore(Settings settings, Environment env, ResourceWatcherService watcherService) {
|
public FileRolesStore(Settings settings, Environment env, ResourceWatcherService watcherService) {
|
||||||
this(settings, env, watcherService, RefreshListener.NOOP);
|
this(settings, env, watcherService, RefreshListener.NOOP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,21 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authz.store;
|
package org.elasticsearch.xpack.security.authz.store;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.LatchedActionListener;
|
import org.elasticsearch.action.LatchedActionListener;
|
||||||
|
@ -29,7 +44,6 @@ import org.elasticsearch.cluster.ClusterStateListener;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Setting.Property;
|
import org.elasticsearch.common.settings.Setting.Property;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
@ -42,6 +56,8 @@ import org.elasticsearch.index.get.GetResult;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool.Names;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
||||||
import org.elasticsearch.xpack.security.action.role.ClearRolesCacheRequest;
|
import org.elasticsearch.xpack.security.action.role.ClearRolesCacheRequest;
|
||||||
|
@ -52,24 +68,7 @@ import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.IndicesPermission.Group;
|
import org.elasticsearch.xpack.security.authz.permission.IndicesPermission.Group;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.Role;
|
import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
import org.elasticsearch.xpack.security.client.SecurityClient;
|
import org.elasticsearch.xpack.security.client.SecurityClient;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool.Cancellable;
|
import org.elasticsearch.threadpool.ThreadPool.Cancellable;
|
||||||
import org.elasticsearch.threadpool.ThreadPool.Names;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
import static org.elasticsearch.xpack.security.Security.setting;
|
import static org.elasticsearch.xpack.security.Security.setting;
|
||||||
|
@ -116,7 +115,6 @@ public class NativeRolesStore extends AbstractComponent implements RolesStore, C
|
||||||
|
|
||||||
private volatile boolean securityIndexExists = false;
|
private volatile boolean securityIndexExists = false;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public NativeRolesStore(Settings settings, InternalClient client, ThreadPool threadPool) {
|
public NativeRolesStore(Settings settings, InternalClient client, ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
|
@ -5,7 +5,12 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authz.store;
|
package org.elasticsearch.xpack.security.authz.store;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.elasticsearch.common.util.set.Sets;
|
import org.elasticsearch.common.util.set.Sets;
|
||||||
import org.elasticsearch.xpack.security.SecurityContext;
|
import org.elasticsearch.xpack.security.SecurityContext;
|
||||||
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
||||||
|
@ -17,12 +22,6 @@ import org.elasticsearch.xpack.security.authz.permission.TransportClientRole;
|
||||||
import org.elasticsearch.xpack.security.user.KibanaUser;
|
import org.elasticsearch.xpack.security.user.KibanaUser;
|
||||||
import org.elasticsearch.xpack.security.user.SystemUser;
|
import org.elasticsearch.xpack.security.user.SystemUser;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +29,6 @@ public class ReservedRolesStore implements RolesStore {
|
||||||
|
|
||||||
private final SecurityContext securityContext;
|
private final SecurityContext securityContext;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ReservedRolesStore(SecurityContext securityContext) {
|
public ReservedRolesStore(SecurityContext securityContext) {
|
||||||
this.securityContext = securityContext;
|
this.securityContext = securityContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.elasticsearch.xpack.XPackFeatureSet;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
import org.elasticsearch.xpack.security.authc.Realm;
|
import org.elasticsearch.xpack.security.authc.Realm;
|
||||||
import org.elasticsearch.xpack.security.authc.Realms;
|
import org.elasticsearch.xpack.security.authc.Realms;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||||
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
||||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||||
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
||||||
|
@ -44,7 +45,7 @@ public class SecurityFeatureSetTests extends ESTestCase {
|
||||||
private Realms realms;
|
private Realms realms;
|
||||||
private NamedWriteableRegistry namedWriteableRegistry;
|
private NamedWriteableRegistry namedWriteableRegistry;
|
||||||
private IPFilter ipFilter;
|
private IPFilter ipFilter;
|
||||||
private RolesStore rolesStore;
|
private CompositeRolesStore rolesStore;
|
||||||
private AuditTrailService auditTrail;
|
private AuditTrailService auditTrail;
|
||||||
private CryptoService cryptoService;
|
private CryptoService cryptoService;
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ public class SecurityFeatureSetTests extends ESTestCase {
|
||||||
realms = mock(Realms.class);
|
realms = mock(Realms.class);
|
||||||
namedWriteableRegistry = mock(NamedWriteableRegistry.class);
|
namedWriteableRegistry = mock(NamedWriteableRegistry.class);
|
||||||
ipFilter = mock(IPFilter.class);
|
ipFilter = mock(IPFilter.class);
|
||||||
rolesStore = mock(RolesStore.class);
|
rolesStore = mock(CompositeRolesStore.class);
|
||||||
auditTrail = mock(AuditTrailService.class);
|
auditTrail = mock(AuditTrailService.class);
|
||||||
cryptoService = mock(CryptoService.class);
|
cryptoService = mock(CryptoService.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
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.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
@ -53,7 +54,8 @@ public class SecurityTests extends ESTestCase {
|
||||||
Environment env = new Environment(settings);
|
Environment env = new Environment(settings);
|
||||||
Security security = new Security(settings, env);
|
Security security = new Security(settings, env);
|
||||||
ThreadPool threadPool = mock(ThreadPool.class);
|
ThreadPool threadPool = mock(ThreadPool.class);
|
||||||
return security.createComponents(null, threadPool, null, null, Arrays.asList(extensions));
|
ClusterService clusterService = mock(ClusterService.class);
|
||||||
|
return security.createComponents(null, threadPool, clusterService, null, Arrays.asList(extensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T findComponent(Class<T> type, Collection<Object> components) {
|
private <T> T findComponent(Class<T> type, Collection<Object> components) {
|
||||||
|
@ -90,7 +92,8 @@ public class SecurityTests extends ESTestCase {
|
||||||
|
|
||||||
public void testDisabledByDefault() throws Exception {
|
public void testDisabledByDefault() throws Exception {
|
||||||
Collection<Object> components = createComponents(Settings.EMPTY);
|
Collection<Object> components = createComponents(Settings.EMPTY);
|
||||||
assertNull(findComponent(AuthenticationService.class, components));
|
AuditTrailService auditTrailService = findComponent(AuditTrailService.class, components);
|
||||||
|
assertEquals(0, auditTrailService.getAuditTrails().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIndexAuditTrail() throws Exception {
|
public void testIndexAuditTrail() throws Exception {
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.xpack.security.authc.Authentication;
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
||||||
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
||||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
|
||||||
import org.elasticsearch.xpack.security.user.SystemUser;
|
import org.elasticsearch.xpack.security.user.SystemUser;
|
||||||
import org.elasticsearch.xpack.security.user.User;
|
import org.elasticsearch.xpack.security.user.User;
|
||||||
|
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
|
@ -14,6 +14,8 @@ import org.elasticsearch.test.ESIntegTestCase.Scope;
|
||||||
import org.elasticsearch.test.InternalTestCluster;
|
import org.elasticsearch.test.InternalTestCluster;
|
||||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||||
import org.elasticsearch.test.SecuritySettingsSource;
|
import org.elasticsearch.test.SecuritySettingsSource;
|
||||||
|
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||||
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -22,6 +24,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -137,10 +140,13 @@ public class RemoteIndexAuditTrailStartingTests extends SecurityIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testThatRemoteAuditInstancesAreStarted() throws Exception {
|
public void testThatRemoteAuditInstancesAreStarted() throws Exception {
|
||||||
Iterable<IndexAuditTrail> auditTrails = remoteCluster.getInstances(IndexAuditTrail.class);
|
AuditTrailService auditTrailService = remoteCluster.getInstance(AuditTrailService.class);
|
||||||
for (final IndexAuditTrail auditTrail : auditTrails) {
|
Optional<AuditTrail> auditTrail = auditTrailService.getAuditTrails().stream()
|
||||||
awaitBusy(() -> auditTrail.state() == IndexAuditTrail.State.STARTED, 2L, TimeUnit.SECONDS);
|
.filter(t -> t.name().equals(IndexAuditTrail.NAME)).findFirst();
|
||||||
assertThat(auditTrail.state(), is(IndexAuditTrail.State.STARTED));
|
assertTrue(auditTrail.isPresent());
|
||||||
}
|
IndexAuditTrail indexAuditTrail = (IndexAuditTrail)auditTrail.get();
|
||||||
|
|
||||||
|
awaitBusy(() -> indexAuditTrail.state() == IndexAuditTrail.State.STARTED, 2L, TimeUnit.SECONDS);
|
||||||
|
assertThat(indexAuditTrail.state(), is(IndexAuditTrail.State.STARTED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ import org.elasticsearch.action.update.UpdateRequest;
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.cluster.service.ClusterService;
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
import org.elasticsearch.common.collect.Tuple;
|
import org.elasticsearch.common.collect.Tuple;
|
||||||
|
@ -65,17 +64,17 @@ import org.elasticsearch.xpack.security.SecurityTemplateService;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication;
|
import org.elasticsearch.xpack.security.authc.Authentication;
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||||
|
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||||
|
import org.elasticsearch.xpack.security.user.SystemUser;
|
||||||
|
import org.elasticsearch.xpack.security.user.User;
|
||||||
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler;
|
import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.Role;
|
import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
|
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.GeneralPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.GeneralPrivilege;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.IndexPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.IndexPrivilege;
|
||||||
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
|
||||||
import org.elasticsearch.xpack.security.user.SystemUser;
|
|
||||||
import org.elasticsearch.xpack.security.user.User;
|
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -85,7 +84,6 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.mockito.AdditionalAnswers.returnsFirstArg;
|
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
@ -95,25 +93,23 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class AuthorizationServiceTests extends ESTestCase {
|
public class AuthorizationServiceTests extends ESTestCase {
|
||||||
private AuditTrailService auditTrail;
|
private AuditTrailService auditTrail;
|
||||||
private RolesStore rolesStore;
|
private CompositeRolesStore rolesStore;
|
||||||
private ClusterService clusterService;
|
private ClusterService clusterService;
|
||||||
private AuthorizationService internalAuthorizationService;
|
private AuthorizationService authorizationService;
|
||||||
private ThreadContext threadContext;
|
private ThreadContext threadContext;
|
||||||
private ThreadPool threadPool;
|
private ThreadPool threadPool;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
rolesStore = mock(RolesStore.class);
|
rolesStore = mock(CompositeRolesStore.class);
|
||||||
clusterService = mock(ClusterService.class);
|
clusterService = mock(ClusterService.class);
|
||||||
auditTrail = mock(AuditTrailService.class);
|
auditTrail = mock(AuditTrailService.class);
|
||||||
threadContext = new ThreadContext(Settings.EMPTY);
|
threadContext = new ThreadContext(Settings.EMPTY);
|
||||||
threadPool = mock(ThreadPool.class);
|
threadPool = mock(ThreadPool.class);
|
||||||
when(threadPool.getThreadContext()).thenReturn(threadContext);
|
when(threadPool.getThreadContext()).thenReturn(threadContext);
|
||||||
|
|
||||||
IndexNameExpressionResolver nameExpressionResolver = mock(IndexNameExpressionResolver.class);
|
authorizationService = new AuthorizationService(Settings.EMPTY, rolesStore, clusterService,
|
||||||
when(nameExpressionResolver.resolveDateMathExpression(any(String.class))).thenAnswer(returnsFirstArg());
|
auditTrail, new DefaultAuthenticationFailureHandler(), threadPool);
|
||||||
internalAuthorizationService = new AuthorizationService(Settings.EMPTY, rolesStore, clusterService,
|
|
||||||
auditTrail, new DefaultAuthenticationFailureHandler(), threadPool, nameExpressionResolver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -125,10 +121,10 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
|
|
||||||
// A failure would throw an exception
|
// A failure would throw an exception
|
||||||
internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:monitor/whatever", request);
|
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:monitor/whatever", request);
|
||||||
verify(auditTrail).accessGranted(SystemUser.INSTANCE, "indices:monitor/whatever", request);
|
verify(auditTrail).accessGranted(SystemUser.INSTANCE, "indices:monitor/whatever", request);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "internal:whatever", request);
|
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "internal:whatever", request);
|
||||||
verify(auditTrail).accessGranted(SystemUser.INSTANCE, "internal:whatever", request);
|
verify(auditTrail).accessGranted(SystemUser.INSTANCE, "internal:whatever", request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +132,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
public void testIndicesActionsAreNotAuthorized() {
|
public void testIndicesActionsAreNotAuthorized() {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:", request);
|
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:", request);
|
||||||
fail("action beginning with indices should have failed");
|
fail("action beginning with indices should have failed");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e,
|
assertAuthorizationException(e,
|
||||||
|
@ -149,7 +145,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
public void testClusterAdminActionsAreNotAuthorized() {
|
public void testClusterAdminActionsAreNotAuthorized() {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/whatever", request);
|
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/whatever", request);
|
||||||
fail("action beginning with cluster:admin/whatever should have failed");
|
fail("action beginning with cluster:admin/whatever should have failed");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e,
|
assertAuthorizationException(e,
|
||||||
|
@ -162,7 +158,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
public void testClusterAdminSnapshotStatusActionIsNotAuthorized() {
|
public void testClusterAdminSnapshotStatusActionIsNotAuthorized() {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/snapshot/status", request);
|
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/snapshot/status", request);
|
||||||
fail("action beginning with cluster:admin/snapshot/status should have failed");
|
fail("action beginning with cluster:admin/snapshot/status should have failed");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" +
|
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" +
|
||||||
|
@ -176,7 +172,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
TransportRequest request = new SearchRequest();
|
TransportRequest request = new SearchRequest();
|
||||||
User user = new User("test user");
|
User user = new User("test user");
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("user without roles should be denied");
|
fail("user without roles should be denied");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
||||||
|
@ -189,7 +185,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
TransportRequest request = new SearchRequest();
|
TransportRequest request = new SearchRequest();
|
||||||
User user = new User("test user", "non-existent-role");
|
User user = new User("test user", "non-existent-role");
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("user with unknown role only should have been denied");
|
fail("user with unknown role only should have been denied");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
||||||
|
@ -204,7 +200,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());
|
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "whatever", request);
|
authorizationService.authorize(createAuthentication(user), "whatever", request);
|
||||||
fail("non indices and non cluster requests should be denied");
|
fail("non indices and non cluster requests should be denied");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [whatever] is unauthorized for user [test user]"));
|
assertAuthorizationException(e, containsString("action [whatever] is unauthorized for user [test user]"));
|
||||||
|
@ -219,7 +215,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
when(rolesStore.role("no_indices")).thenReturn(Role.builder("no_indices").cluster(ClusterPrivilege.action("")).build());
|
when(rolesStore.role("no_indices")).thenReturn(Role.builder("no_indices").cluster(ClusterPrivilege.action("")).build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("user only has cluster roles so indices requests should fail");
|
fail("user only has cluster roles so indices requests should fail");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
||||||
|
@ -233,29 +229,29 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());
|
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());
|
||||||
|
|
||||||
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
|
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), ClearScrollAction.NAME, clearScrollRequest);
|
authorizationService.authorize(createAuthentication(user), ClearScrollAction.NAME, clearScrollRequest);
|
||||||
verify(auditTrail).accessGranted(user, ClearScrollAction.NAME, clearScrollRequest);
|
verify(auditTrail).accessGranted(user, ClearScrollAction.NAME, clearScrollRequest);
|
||||||
|
|
||||||
SearchScrollRequest searchScrollRequest = new SearchScrollRequest();
|
SearchScrollRequest searchScrollRequest = new SearchScrollRequest();
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), SearchScrollAction.NAME, searchScrollRequest);
|
authorizationService.authorize(createAuthentication(user), SearchScrollAction.NAME, searchScrollRequest);
|
||||||
verify(auditTrail).accessGranted(user, SearchScrollAction.NAME, searchScrollRequest);
|
verify(auditTrail).accessGranted(user, SearchScrollAction.NAME, searchScrollRequest);
|
||||||
|
|
||||||
// We have to use a mock request for other Scroll actions as the actual requests are package private to SearchTransportService
|
// We have to use a mock request for other Scroll actions as the actual requests are package private to SearchTransportService
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
internalAuthorizationService
|
authorizationService
|
||||||
.authorize(createAuthentication(user), SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request);
|
.authorize(createAuthentication(user), SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request);
|
verify(auditTrail).accessGranted(user, SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request);
|
authorizationService.authorize(createAuthentication(user), SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request);
|
verify(auditTrail).accessGranted(user, SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request);
|
authorizationService.authorize(createAuthentication(user), SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request);
|
verify(auditTrail).accessGranted(user, SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.QUERY_SCROLL_ACTION_NAME, request);
|
authorizationService.authorize(createAuthentication(user), SearchTransportService.QUERY_SCROLL_ACTION_NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, SearchTransportService.QUERY_SCROLL_ACTION_NAME, request);
|
verify(auditTrail).accessGranted(user, SearchTransportService.QUERY_SCROLL_ACTION_NAME, request);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request);
|
authorizationService.authorize(createAuthentication(user), SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request);
|
verify(auditTrail).accessGranted(user, SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
}
|
}
|
||||||
|
@ -269,7 +265,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("indices request for b should be denied since there is no such index");
|
fail("indices request for b should be denied since there is no such index");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
|
||||||
|
@ -290,7 +286,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request);
|
authorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request);
|
||||||
fail("indices creation request with alias should be denied since user does not have permission to alias");
|
fail("indices creation request with alias should be denied since user does not have permission to alias");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e,
|
assertAuthorizationException(e,
|
||||||
|
@ -311,7 +307,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
when(clusterService.state()).thenReturn(state);
|
when(clusterService.state()).thenReturn(state);
|
||||||
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request);
|
authorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request);
|
||||||
|
|
||||||
verify(auditTrail).accessGranted(user, CreateIndexAction.NAME, request);
|
verify(auditTrail).accessGranted(user, CreateIndexAction.NAME, request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
|
@ -322,7 +318,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
public void testIndicesAliasesWithNoRolesUser() {
|
public void testIndicesAliasesWithNoRolesUser() {
|
||||||
User user = new User("test user");
|
User user = new User("test user");
|
||||||
|
|
||||||
List<String> list = internalAuthorizationService.authorizedIndicesAndAliases(user, "");
|
List<String> list = authorizationService.authorizedIndicesAndAliases(user, "");
|
||||||
assertThat(list.isEmpty(), is(true));
|
assertThat(list.isEmpty(), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +343,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
.build(), true)
|
.build(), true)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
List<String> list = internalAuthorizationService.authorizedIndicesAndAliases(user, SearchAction.NAME);
|
List<String> list = authorizationService.authorizedIndicesAndAliases(user, SearchAction.NAME);
|
||||||
assertThat(list, containsInAnyOrder("a1", "a2", "aaaaaa", "b", "ab"));
|
assertThat(list, containsInAnyOrder("a1", "a2", "aaaaaa", "b", "ab"));
|
||||||
assertThat(list.contains("bbbbb"), is(false));
|
assertThat(list.contains("bbbbb"), is(false));
|
||||||
assertThat(list.contains("ba"), is(false));
|
assertThat(list.contains("ba"), is(false));
|
||||||
|
@ -357,17 +353,15 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
TransportRequest request = new IndicesExistsRequest("b");
|
TransportRequest request = new IndicesExistsRequest("b");
|
||||||
ClusterState state = mock(ClusterState.class);
|
ClusterState state = mock(ClusterState.class);
|
||||||
AnonymousUser.initialize(Settings.builder().put(AnonymousUser.ROLES_SETTING.getKey(), "a_all").build());
|
AnonymousUser.initialize(Settings.builder().put(AnonymousUser.ROLES_SETTING.getKey(), "a_all").build());
|
||||||
IndexNameExpressionResolver nameExpressionResolver = mock(IndexNameExpressionResolver.class);
|
authorizationService = new AuthorizationService(Settings.EMPTY, rolesStore, clusterService, auditTrail,
|
||||||
when(nameExpressionResolver.resolveDateMathExpression(any(String.class))).thenAnswer(returnsFirstArg());
|
new DefaultAuthenticationFailureHandler(), threadPool);
|
||||||
internalAuthorizationService = new AuthorizationService(Settings.EMPTY, rolesStore, clusterService, auditTrail,
|
|
||||||
new DefaultAuthenticationFailureHandler(), threadPool, nameExpressionResolver);
|
|
||||||
|
|
||||||
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_all").add(IndexPrivilege.ALL, "a").build());
|
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_all").add(IndexPrivilege.ALL, "a").build());
|
||||||
when(clusterService.state()).thenReturn(state);
|
when(clusterService.state()).thenReturn(state);
|
||||||
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(AnonymousUser.INSTANCE), "indices:a", request);
|
authorizationService.authorize(createAuthentication(AnonymousUser.INSTANCE), "indices:a", request);
|
||||||
fail("indices request for b should be denied since there is no such index");
|
fail("indices request for b should be denied since there is no such index");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e,
|
assertAuthorizationException(e,
|
||||||
|
@ -387,18 +381,16 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
.put(AuthorizationService.ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING.getKey(), false)
|
.put(AuthorizationService.ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING.getKey(), false)
|
||||||
.build());
|
.build());
|
||||||
User anonymousUser = AnonymousUser.INSTANCE;
|
User anonymousUser = AnonymousUser.INSTANCE;
|
||||||
IndexNameExpressionResolver nameExpressionResolver = mock(IndexNameExpressionResolver.class);
|
authorizationService = new AuthorizationService(
|
||||||
when(nameExpressionResolver.resolveDateMathExpression(any(String.class))).thenAnswer(returnsFirstArg());
|
|
||||||
internalAuthorizationService = new AuthorizationService(
|
|
||||||
Settings.builder().put(AuthorizationService.ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING.getKey(), false).build(),
|
Settings.builder().put(AuthorizationService.ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING.getKey(), false).build(),
|
||||||
rolesStore, clusterService, auditTrail, new DefaultAuthenticationFailureHandler(), threadPool, nameExpressionResolver);
|
rolesStore, clusterService, auditTrail, new DefaultAuthenticationFailureHandler(), threadPool);
|
||||||
|
|
||||||
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_all").add(IndexPrivilege.ALL, "a").build());
|
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_all").add(IndexPrivilege.ALL, "a").build());
|
||||||
when(clusterService.state()).thenReturn(state);
|
when(clusterService.state()).thenReturn(state);
|
||||||
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(anonymousUser), "indices:a", request);
|
authorizationService.authorize(createAuthentication(anonymousUser), "indices:a", request);
|
||||||
fail("indices request for b should be denied since there is no such index");
|
fail("indices request for b should be denied since there is no such index");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthenticationException(e, containsString("action [indices:a] requires authentication"));
|
assertAuthenticationException(e, containsString("action [indices:a] requires authentication"));
|
||||||
|
@ -414,7 +406,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
User user = new User("test user", null, new User("run as me", new String[] { "admin" }));
|
User user = new User("test user", null, new User("run as me", new String[] { "admin" }));
|
||||||
assertThat(user.runAs(), is(notNullValue()));
|
assertThat(user.runAs(), is(notNullValue()));
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("user without roles should be denied for run as");
|
fail("user without roles should be denied for run as");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
|
||||||
|
@ -434,7 +426,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("user without roles should be denied for run as");
|
fail("user without roles should be denied for run as");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
|
||||||
|
@ -468,7 +460,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
fail("the run as user's role doesn't exist so they should not get authorized");
|
fail("the run as user's role doesn't exist so they should not get authorized");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
|
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
|
||||||
|
@ -499,7 +491,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
.add(IndexPrivilege.ALL, "b")
|
.add(IndexPrivilege.ALL, "b")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request);
|
authorizationService.authorize(createAuthentication(user), "indices:a", request);
|
||||||
verify(auditTrail).runAsGranted(user, "indices:a", request);
|
verify(auditTrail).runAsGranted(user, "indices:a", request);
|
||||||
verify(auditTrail).accessGranted(user, "indices:a", request);
|
verify(auditTrail).accessGranted(user, "indices:a", request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
|
@ -538,7 +530,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
String action = requestTuple.v1();
|
String action = requestTuple.v1();
|
||||||
TransportRequest request = requestTuple.v2();
|
TransportRequest request = requestTuple.v2();
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), action, request);
|
authorizationService.authorize(createAuthentication(user), action, request);
|
||||||
fail("only the xpack user can execute operation [" + action + "] against the internal index");
|
fail("only the xpack user can execute operation [" + action + "] against the internal index");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [" + action + "] is unauthorized for user [all_access_user]"));
|
assertAuthorizationException(e, containsString("action [" + action + "] is unauthorized for user [all_access_user]"));
|
||||||
|
@ -549,12 +541,12 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
// we should allow waiting for the health of the index or any index if the user has this permission
|
// we should allow waiting for the health of the index or any index if the user has this permission
|
||||||
ClusterHealthRequest request = new ClusterHealthRequest(SecurityTemplateService.SECURITY_INDEX_NAME);
|
ClusterHealthRequest request = new ClusterHealthRequest(SecurityTemplateService.SECURITY_INDEX_NAME);
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), ClusterHealthAction.NAME, request);
|
authorizationService.authorize(createAuthentication(user), ClusterHealthAction.NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, ClusterHealthAction.NAME, request);
|
verify(auditTrail).accessGranted(user, ClusterHealthAction.NAME, request);
|
||||||
|
|
||||||
// multiple indices
|
// multiple indices
|
||||||
request = new ClusterHealthRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "foo", "bar");
|
request = new ClusterHealthRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "foo", "bar");
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), ClusterHealthAction.NAME, request);
|
authorizationService.authorize(createAuthentication(user), ClusterHealthAction.NAME, request);
|
||||||
verify(auditTrail).accessGranted(user, ClusterHealthAction.NAME, request);
|
verify(auditTrail).accessGranted(user, ClusterHealthAction.NAME, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +578,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
for (Tuple<String, ? extends TransportRequest> requestTuple : requests) {
|
for (Tuple<String, ? extends TransportRequest> requestTuple : requests) {
|
||||||
String action = requestTuple.v1();
|
String action = requestTuple.v1();
|
||||||
TransportRequest request = requestTuple.v2();
|
TransportRequest request = requestTuple.v2();
|
||||||
internalAuthorizationService.authorize(createAuthentication(user), action, request);
|
authorizationService.authorize(createAuthentication(user), action, request);
|
||||||
verify(auditTrail).accessGranted(user, action, request);
|
verify(auditTrail).accessGranted(user, action, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,7 +612,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
for (Tuple<String, TransportRequest> requestTuple : requests) {
|
for (Tuple<String, TransportRequest> requestTuple : requests) {
|
||||||
String action = requestTuple.v1();
|
String action = requestTuple.v1();
|
||||||
TransportRequest request = requestTuple.v2();
|
TransportRequest request = requestTuple.v2();
|
||||||
internalAuthorizationService.authorize(createAuthentication(XPackUser.INSTANCE), action, request);
|
authorizationService.authorize(createAuthentication(XPackUser.INSTANCE), action, request);
|
||||||
verify(auditTrail).accessGranted(XPackUser.INSTANCE, action, request);
|
verify(auditTrail).accessGranted(XPackUser.INSTANCE, action, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@ import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
||||||
|
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||||
|
import org.elasticsearch.xpack.security.user.User;
|
||||||
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
|
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler;
|
import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
||||||
|
@ -41,9 +45,6 @@ import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
|
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
|
||||||
import org.elasticsearch.xpack.security.authz.privilege.IndexPrivilege;
|
import org.elasticsearch.xpack.security.authz.privilege.IndexPrivilege;
|
||||||
import org.elasticsearch.xpack.security.authz.store.RolesStore;
|
|
||||||
import org.elasticsearch.xpack.security.user.User;
|
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
import static org.hamcrest.Matchers.arrayContaining;
|
||||||
|
@ -60,7 +61,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
|
||||||
|
|
||||||
private User user;
|
private User user;
|
||||||
private User userNoIndices;
|
private User userNoIndices;
|
||||||
private RolesStore rolesStore;
|
private CompositeRolesStore rolesStore;
|
||||||
private MetaData metaData;
|
private MetaData metaData;
|
||||||
private DefaultIndicesAndAliasesResolver defaultIndicesResolver;
|
private DefaultIndicesAndAliasesResolver defaultIndicesResolver;
|
||||||
private IndexNameExpressionResolver indexNameExpressionResolver;
|
private IndexNameExpressionResolver indexNameExpressionResolver;
|
||||||
|
@ -91,7 +92,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
|
||||||
|
|
||||||
user = new User("user", "role");
|
user = new User("user", "role");
|
||||||
userNoIndices = new User("test", "test");
|
userNoIndices = new User("test", "test");
|
||||||
rolesStore = mock(RolesStore.class);
|
rolesStore = mock(CompositeRolesStore.class);
|
||||||
String[] authorizedIndices = new String[] { "bar", "bar-closed", "foofoobar", "foofoo", "missing", "foofoo-closed" };
|
String[] authorizedIndices = new String[] { "bar", "bar-closed", "foofoobar", "foofoo", "missing", "foofoo-closed" };
|
||||||
when(rolesStore.role("role")).thenReturn(Role.builder("role").add(IndexPrivilege.ALL, authorizedIndices).build());
|
when(rolesStore.role("role")).thenReturn(Role.builder("role").add(IndexPrivilege.ALL, authorizedIndices).build());
|
||||||
when(rolesStore.role("test")).thenReturn(Role.builder("test").cluster(ClusterPrivilege.MONITOR).build());
|
when(rolesStore.role("test")).thenReturn(Role.builder("test").cluster(ClusterPrivilege.MONITOR).build());
|
||||||
|
@ -102,8 +103,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
|
||||||
when(state.metaData()).thenReturn(metaData);
|
when(state.metaData()).thenReturn(metaData);
|
||||||
|
|
||||||
AuthorizationService authzService = new AuthorizationService(settings, rolesStore, clusterService,
|
AuthorizationService authzService = new AuthorizationService(settings, rolesStore, clusterService,
|
||||||
mock(AuditTrailService.class), new DefaultAuthenticationFailureHandler(), mock(ThreadPool.class),
|
mock(AuditTrailService.class), new DefaultAuthenticationFailureHandler(), mock(ThreadPool.class));
|
||||||
indexNameExpressionResolver);
|
|
||||||
defaultIndicesResolver = new DefaultIndicesAndAliasesResolver(authzService, indexNameExpressionResolver);
|
defaultIndicesResolver = new DefaultIndicesAndAliasesResolver(authzService, indexNameExpressionResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,6 @@ import org.elasticsearch.xpack.rest.action.RestXPackInfoAction;
|
||||||
import org.elasticsearch.xpack.rest.action.RestXPackUsageAction;
|
import org.elasticsearch.xpack.rest.action.RestXPackUsageAction;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
import org.elasticsearch.xpack.security.Security;
|
import org.elasticsearch.xpack.security.Security;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationModule;
|
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
||||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.xpack.support.clock.Clock;
|
import org.elasticsearch.xpack.support.clock.Clock;
|
||||||
|
@ -180,7 +179,6 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
||||||
public Collection<Class<? extends LifecycleComponent>> getGuiceServiceClasses() {
|
public Collection<Class<? extends LifecycleComponent>> getGuiceServiceClasses() {
|
||||||
ArrayList<Class<? extends LifecycleComponent>> services = new ArrayList<>();
|
ArrayList<Class<? extends LifecycleComponent>> services = new ArrayList<>();
|
||||||
services.addAll(notification.nodeServices());
|
services.addAll(notification.nodeServices());
|
||||||
services.addAll(security.nodeServices());
|
|
||||||
services.addAll(monitoring.nodeServices());
|
services.addAll(monitoring.nodeServices());
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -315,12 +313,6 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
||||||
return security.getProcessors(parameters);
|
return security.getProcessors(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(AuthenticationModule module) {
|
|
||||||
if (extensionsService != null) {
|
|
||||||
extensionsService.onModule(module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onIndexModule(IndexModule module) {
|
public void onIndexModule(IndexModule module) {
|
||||||
security.onIndexModule(module);
|
security.onIndexModule(module);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationModule;
|
|
||||||
import org.elasticsearch.xpack.security.authc.Realm;
|
import org.elasticsearch.xpack.security.authc.Realm;
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,11 +27,6 @@ public abstract class XPackExtension {
|
||||||
*/
|
*/
|
||||||
public abstract String description();
|
public abstract String description();
|
||||||
|
|
||||||
/**
|
|
||||||
* Implement this function to register custom extensions in the authentication module.
|
|
||||||
*/
|
|
||||||
public void onModule(AuthenticationModule module) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns headers which should be copied from REST requests to internal cluster requests.
|
* Returns headers which should be copied from REST requests to internal cluster requests.
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +34,6 @@ public abstract class XPackExtension {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns authentication realm implementations added by this extension.
|
* Returns authentication realm implementations added by this extension.
|
||||||
*
|
*
|
||||||
|
@ -52,4 +44,14 @@ public abstract class XPackExtension {
|
||||||
public Map<String, Realm.Factory> getRealms() {
|
public Map<String, Realm.Factory> getRealms() {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a handler for authentication failures, or null to use the default handler.
|
||||||
|
*
|
||||||
|
* Only one installed extension may have an authentication failure handler. If more than
|
||||||
|
* one extension returns a non-null handler, an error is raised.
|
||||||
|
*/
|
||||||
|
public AuthenticationFailureHandler getAuthenticationFailureHandler() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.elasticsearch.common.io.FileSystemUtils;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationModule;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -74,12 +73,6 @@ public class XPackExtensionsService {
|
||||||
extensions = Collections.unmodifiableList(extensionsLoaded);
|
extensions = Collections.unmodifiableList(extensionsLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(AuthenticationModule module) {
|
|
||||||
for (Tuple<XPackExtensionInfo, XPackExtension> tuple : extensions) {
|
|
||||||
tuple.v2().onModule(module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<XPackExtension> getExtensions() {
|
public List<XPackExtension> getExtensions() {
|
||||||
return extensions.stream().map(Tuple::v2).collect(Collectors.toList());
|
return extensions.stream().map(Tuple::v2).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue