Add specific client and user for security index access (elastic/x-pack-elasticsearch#2492)
This change removes security index access from the xpack user by creating its own specific role and adds a xpack security user that maintains the superuser role so that it can perform all operations necessary for security. Original commit: elastic/x-pack-elasticsearch@ad906bc913
This commit is contained in:
parent
104a3a323f
commit
8d8baffe24
|
@ -283,7 +283,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
||||||
components.add(licenseState);
|
components.add(licenseState);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
components.addAll(security.createComponents(internalClient, threadPool, clusterService, resourceWatcherService,
|
components.addAll(security.createComponents(client, threadPool, clusterService, resourceWatcherService,
|
||||||
extensionsService.getExtensions()));
|
extensionsService.getExtensions()));
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new IllegalStateException("security initialization failed", e);
|
throw new IllegalStateException("security initialization failed", e);
|
||||||
|
@ -319,7 +319,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
||||||
|
|
||||||
components.addAll(logstash.createComponents(internalClient, clusterService));
|
components.addAll(logstash.createComponents(internalClient, clusterService));
|
||||||
|
|
||||||
components.addAll(upgrade.createComponents(internalClient, clusterService, threadPool, resourceWatcherService,
|
components.addAll(upgrade.createComponents(client, clusterService, threadPool, resourceWatcherService,
|
||||||
scriptService, xContentRegistry));
|
scriptService, xContentRegistry));
|
||||||
|
|
||||||
// just create the reloader as it will pull all of the loaded ssl configurations and start watching them
|
// just create the reloader as it will pull all of the loaded ssl configurations and start watching them
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.XPackSettings;
|
import org.elasticsearch.xpack.XPackSettings;
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication;
|
import org.elasticsearch.xpack.security.authc.Authentication;
|
||||||
|
import org.elasticsearch.xpack.security.user.User;
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -48,15 +49,21 @@ public class InternalClient extends FilterClient {
|
||||||
|
|
||||||
private final String nodeName;
|
private final String nodeName;
|
||||||
private final boolean securityEnabled;
|
private final boolean securityEnabled;
|
||||||
|
private final User user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an InternalClient.
|
* Constructs an InternalClient.
|
||||||
* If security is enabled the client is secure. Otherwise this client is a passthrough.
|
* If security is enabled the client is secure. Otherwise this client is a passthrough.
|
||||||
*/
|
*/
|
||||||
public InternalClient(Settings settings, ThreadPool threadPool, Client in) {
|
public InternalClient(Settings settings, ThreadPool threadPool, Client in) {
|
||||||
|
this(settings, threadPool, in, XPackUser.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalClient(Settings settings, ThreadPool threadPool, Client in, User user) {
|
||||||
super(settings, threadPool, in);
|
super(settings, threadPool, in);
|
||||||
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
|
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
|
||||||
this.securityEnabled = XPackSettings.SECURITY_ENABLED.get(settings);
|
this.securityEnabled = XPackSettings.SECURITY_ENABLED.get(settings);
|
||||||
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,7 +87,7 @@ public class InternalClient extends FilterClient {
|
||||||
|
|
||||||
protected void processContext(ThreadContext threadContext) {
|
protected void processContext(ThreadContext threadContext) {
|
||||||
try {
|
try {
|
||||||
Authentication authentication = new Authentication(XPackUser.INSTANCE,
|
Authentication authentication = new Authentication(user,
|
||||||
new Authentication.RealmRef("__attach", "__attach", nodeName), null);
|
new Authentication.RealmRef("__attach", "__attach", nodeName), null);
|
||||||
authentication.writeToContext(threadContext);
|
authentication.writeToContext(threadContext);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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.client.Client;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.xpack.security.user.XPackSecurityUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special filter client for internal usage by security to modify the security index.
|
||||||
|
*
|
||||||
|
* The {@link XPackSecurityUser} user is added to the execution context before each action is executed.
|
||||||
|
*/
|
||||||
|
public class InternalSecurityClient extends InternalClient {
|
||||||
|
|
||||||
|
public InternalSecurityClient(Settings settings, ThreadPool threadPool, Client in) {
|
||||||
|
super(settings, threadPool, in, XPackSecurityUser.INSTANCE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.action.support.ActionFilter;
|
import org.elasticsearch.action.support.ActionFilter;
|
||||||
import org.elasticsearch.action.support.DestructiveOperations;
|
import org.elasticsearch.action.support.DestructiveOperations;
|
||||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.LocalNodeMasterListener;
|
import org.elasticsearch.cluster.LocalNodeMasterListener;
|
||||||
import org.elasticsearch.cluster.NamedDiff;
|
import org.elasticsearch.cluster.NamedDiff;
|
||||||
|
@ -295,12 +296,13 @@ public class Security implements ActionPlugin, IngestPlugin, NetworkPlugin, Clus
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Object> createComponents(InternalClient client, ThreadPool threadPool, ClusterService clusterService,
|
public Collection<Object> createComponents(Client nodeClient, ThreadPool threadPool, ClusterService clusterService,
|
||||||
ResourceWatcherService resourceWatcherService,
|
ResourceWatcherService resourceWatcherService,
|
||||||
List<XPackExtension> extensions) throws Exception {
|
List<XPackExtension> extensions) throws Exception {
|
||||||
if (enabled == false) {
|
if (enabled == false) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
final InternalSecurityClient client = new InternalSecurityClient(settings, threadPool, nodeClient);
|
||||||
threadContext.set(threadPool.getThreadContext());
|
threadContext.set(threadPool.getThreadContext());
|
||||||
List<Object> components = new ArrayList<>();
|
List<Object> components = new ArrayList<>();
|
||||||
securityContext.set(new SecurityContext(settings, threadPool.getThreadContext()));
|
securityContext.set(new SecurityContext(settings, threadPool.getThreadContext()));
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class SecurityLifecycleService extends AbstractComponent implements Clust
|
||||||
private final IndexLifecycleManager securityIndex;
|
private final IndexLifecycleManager securityIndex;
|
||||||
|
|
||||||
public SecurityLifecycleService(Settings settings, ClusterService clusterService,
|
public SecurityLifecycleService(Settings settings, ClusterService clusterService,
|
||||||
ThreadPool threadPool, InternalClient client,
|
ThreadPool threadPool, InternalSecurityClient client,
|
||||||
@Nullable IndexAuditTrail indexAuditTrail) {
|
@Nullable IndexAuditTrail indexAuditTrail) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportMessage;
|
import org.elasticsearch.transport.TransportMessage;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditLevel;
|
import org.elasticsearch.xpack.security.audit.AuditLevel;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
|
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
|
||||||
|
@ -177,7 +178,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexAuditTrail(Settings settings, InternalClient client, ThreadPool threadPool, ClusterService clusterService) {
|
public IndexAuditTrail(Settings settings, InternalSecurityClient client, ThreadPool threadPool, ClusterService clusterService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool.Names;
|
import org.elasticsearch.threadpool.ThreadPool.Names;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -30,12 +31,12 @@ import static org.elasticsearch.action.support.TransportActions.isShardNotAvaila
|
||||||
*/
|
*/
|
||||||
final class ExpiredTokenRemover extends AbstractRunnable {
|
final class ExpiredTokenRemover extends AbstractRunnable {
|
||||||
|
|
||||||
private final InternalClient client;
|
private final InternalSecurityClient client;
|
||||||
private final AtomicBoolean inProgress = new AtomicBoolean(false);
|
private final AtomicBoolean inProgress = new AtomicBoolean(false);
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final TimeValue timeout;
|
private final TimeValue timeout;
|
||||||
|
|
||||||
ExpiredTokenRemover(Settings settings, InternalClient internalClient) {
|
ExpiredTokenRemover(Settings settings, InternalSecurityClient internalClient) {
|
||||||
this.client = internalClient;
|
this.client = internalClient;
|
||||||
this.logger = Loggers.getLogger(getClass(), settings);
|
this.logger = Loggers.getLogger(getClass(), settings);
|
||||||
this.timeout = TokenService.DELETE_TIMEOUT.get(settings);
|
this.timeout = TokenService.DELETE_TIMEOUT.get(settings);
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.XPackSettings;
|
import org.elasticsearch.xpack.XPackSettings;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
|
@ -132,7 +133,7 @@ public final class TokenService extends AbstractComponent {
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final TimeValue expirationDelay;
|
private final TimeValue expirationDelay;
|
||||||
private final TimeValue deleteInterval;
|
private final TimeValue deleteInterval;
|
||||||
private final InternalClient internalClient;
|
private final InternalSecurityClient internalClient;
|
||||||
private final SecurityLifecycleService lifecycleService;
|
private final SecurityLifecycleService lifecycleService;
|
||||||
private final ExpiredTokenRemover expiredTokenRemover;
|
private final ExpiredTokenRemover expiredTokenRemover;
|
||||||
private final boolean enabled;
|
private final boolean enabled;
|
||||||
|
@ -148,7 +149,7 @@ public final class TokenService extends AbstractComponent {
|
||||||
* @param clock the clock that will be used for comparing timestamps
|
* @param clock the clock that will be used for comparing timestamps
|
||||||
* @param internalClient the client to use when checking for revocations
|
* @param internalClient the client to use when checking for revocations
|
||||||
*/
|
*/
|
||||||
public TokenService(Settings settings, Clock clock, InternalClient internalClient,
|
public TokenService(Settings settings, Clock clock, InternalSecurityClient internalClient,
|
||||||
SecurityLifecycleService lifecycleService, ClusterService clusterService) throws GeneralSecurityException {
|
SecurityLifecycleService lifecycleService, ClusterService clusterService) throws GeneralSecurityException {
|
||||||
super(settings);
|
super(settings);
|
||||||
byte[] saltArr = new byte[SALT_BYTES];
|
byte[] saltArr = new byte[SALT_BYTES];
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheRequest;
|
import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheRequest;
|
||||||
import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheResponse;
|
import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheResponse;
|
||||||
|
@ -73,12 +74,12 @@ public class NativeUsersStore extends AbstractComponent {
|
||||||
|
|
||||||
|
|
||||||
private final Hasher hasher = Hasher.BCRYPT;
|
private final Hasher hasher = Hasher.BCRYPT;
|
||||||
private final InternalClient client;
|
private final InternalSecurityClient client;
|
||||||
private final boolean isTribeNode;
|
private final boolean isTribeNode;
|
||||||
|
|
||||||
private volatile SecurityLifecycleService securityLifecycleService;
|
private volatile SecurityLifecycleService securityLifecycleService;
|
||||||
|
|
||||||
public NativeUsersStore(Settings settings, InternalClient client, SecurityLifecycleService securityLifecycleService) {
|
public NativeUsersStore(Settings settings, InternalSecurityClient client, SecurityLifecycleService securityLifecycleService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.isTribeNode = XPackPlugin.isTribeNode(settings);
|
this.isTribeNode = XPackPlugin.isTribeNode(settings);
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.action.rolemapping.DeleteRoleMappingRequest;
|
import org.elasticsearch.xpack.security.action.rolemapping.DeleteRoleMappingRequest;
|
||||||
import org.elasticsearch.xpack.security.action.rolemapping.PutRoleMappingRequest;
|
import org.elasticsearch.xpack.security.action.rolemapping.PutRoleMappingRequest;
|
||||||
|
@ -70,12 +71,12 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
|
||||||
|
|
||||||
private static final String SECURITY_GENERIC_TYPE = "doc";
|
private static final String SECURITY_GENERIC_TYPE = "doc";
|
||||||
|
|
||||||
private final InternalClient client;
|
private final InternalSecurityClient client;
|
||||||
private final boolean isTribeNode;
|
private final boolean isTribeNode;
|
||||||
private final SecurityLifecycleService securityLifecycleService;
|
private final SecurityLifecycleService securityLifecycleService;
|
||||||
private final List<String> realmsToRefresh = new CopyOnWriteArrayList<>();
|
private final List<String> realmsToRefresh = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public NativeRoleMappingStore(Settings settings, InternalClient client, SecurityLifecycleService securityLifecycleService) {
|
public NativeRoleMappingStore(Settings settings, InternalSecurityClient client, SecurityLifecycleService securityLifecycleService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.isTribeNode = XPackPlugin.isTribeNode(settings);
|
this.isTribeNode = XPackPlugin.isTribeNode(settings);
|
||||||
|
|
|
@ -68,6 +68,7 @@ import org.elasticsearch.xpack.security.support.Automatons;
|
||||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||||
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.user.XPackSecurityUser;
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.Security.setting;
|
import static org.elasticsearch.xpack.security.Security.setting;
|
||||||
|
@ -290,7 +291,6 @@ public class AuthorizationService extends AbstractComponent {
|
||||||
throw denial(authentication, action, request);
|
throw denial(authentication, action, request);
|
||||||
} else if (indicesAccessControl.getIndexPermissions(SecurityLifecycleService.SECURITY_INDEX_NAME) != null
|
} else if (indicesAccessControl.getIndexPermissions(SecurityLifecycleService.SECURITY_INDEX_NAME) != null
|
||||||
&& indicesAccessControl.getIndexPermissions(SecurityLifecycleService.SECURITY_INDEX_NAME).isGranted()
|
&& indicesAccessControl.getIndexPermissions(SecurityLifecycleService.SECURITY_INDEX_NAME).isGranted()
|
||||||
&& XPackUser.is(authentication.getUser()) == false
|
|
||||||
&& MONITOR_INDEX_PREDICATE.test(action) == false
|
&& MONITOR_INDEX_PREDICATE.test(action) == false
|
||||||
&& isSuperuser(authentication.getUser()) == false) {
|
&& isSuperuser(authentication.getUser()) == false) {
|
||||||
// only the XPackUser is allowed to work with this index, but we should allow indices monitoring actions through for debugging
|
// only the XPackUser is allowed to work with this index, but we should allow indices monitoring actions through for debugging
|
||||||
|
@ -392,7 +392,11 @@ public class AuthorizationService extends AbstractComponent {
|
||||||
" roles");
|
" roles");
|
||||||
}
|
}
|
||||||
if (XPackUser.is(user)) {
|
if (XPackUser.is(user)) {
|
||||||
assert XPackUser.INSTANCE.roles().length == 1 && ReservedRolesStore.SUPERUSER_ROLE.name().equals(XPackUser.INSTANCE.roles()[0]);
|
assert XPackUser.INSTANCE.roles().length == 1;
|
||||||
|
roleActionListener.onResponse(XPackUser.ROLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (XPackSecurityUser.is(user)) {
|
||||||
roleActionListener.onResponse(ReservedRolesStore.SUPERUSER_ROLE);
|
roleActionListener.onResponse(ReservedRolesStore.SUPERUSER_ROLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.license.LicenseUtils;
|
||||||
import org.elasticsearch.license.XPackLicenseState;
|
import org.elasticsearch.license.XPackLicenseState;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.action.role.ClearRolesCacheRequest;
|
import org.elasticsearch.xpack.security.action.role.ClearRolesCacheRequest;
|
||||||
import org.elasticsearch.xpack.security.action.role.ClearRolesCacheResponse;
|
import org.elasticsearch.xpack.security.action.role.ClearRolesCacheResponse;
|
||||||
|
@ -79,14 +80,14 @@ public class NativeRolesStore extends AbstractComponent {
|
||||||
TimeValue.timeValueMinutes(20), Property.NodeScope, Property.Deprecated);
|
TimeValue.timeValueMinutes(20), Property.NodeScope, Property.Deprecated);
|
||||||
private static final String ROLE_DOC_TYPE = "doc";
|
private static final String ROLE_DOC_TYPE = "doc";
|
||||||
|
|
||||||
private final InternalClient client;
|
private final InternalSecurityClient client;
|
||||||
private final XPackLicenseState licenseState;
|
private final XPackLicenseState licenseState;
|
||||||
private final boolean isTribeNode;
|
private final boolean isTribeNode;
|
||||||
|
|
||||||
private SecurityClient securityClient;
|
private SecurityClient securityClient;
|
||||||
private final SecurityLifecycleService securityLifecycleService;
|
private final SecurityLifecycleService securityLifecycleService;
|
||||||
|
|
||||||
public NativeRolesStore(Settings settings, InternalClient client, XPackLicenseState licenseState,
|
public NativeRolesStore(Settings settings, InternalSecurityClient client, XPackLicenseState licenseState,
|
||||||
SecurityLifecycleService securityLifecycleService) {
|
SecurityLifecycleService securityLifecycleService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
import org.elasticsearch.xpack.security.support.MetadataUtils;
|
import org.elasticsearch.xpack.security.support.MetadataUtils;
|
||||||
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 org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
import org.elasticsearch.xpack.watcher.execution.TriggeredWatchStore;
|
import org.elasticsearch.xpack.watcher.execution.TriggeredWatchStore;
|
||||||
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
||||||
import org.elasticsearch.xpack.watcher.watch.Watch;
|
import org.elasticsearch.xpack.watcher.watch.Watch;
|
||||||
|
@ -126,7 +127,7 @@ public class ReservedRolesStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isReserved(String role) {
|
public static boolean isReserved(String role) {
|
||||||
return RESERVED_ROLES.containsKey(role) || SystemUser.ROLE_NAME.equals(role);
|
return RESERVED_ROLES.containsKey(role) || SystemUser.ROLE_NAME.equals(role) || XPackUser.ROLE_NAME.equals(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.template.TemplateUtils;
|
import org.elasticsearch.xpack.template.TemplateUtils;
|
||||||
import org.elasticsearch.xpack.upgrade.IndexUpgradeCheck;
|
import org.elasticsearch.xpack.upgrade.IndexUpgradeCheck;
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ public class IndexLifecycleManager extends AbstractComponent {
|
||||||
|
|
||||||
private final String indexName;
|
private final String indexName;
|
||||||
private final String templateName;
|
private final String templateName;
|
||||||
private final InternalClient client;
|
private final InternalSecurityClient client;
|
||||||
|
|
||||||
private final List<BiConsumer<ClusterIndexHealth, ClusterIndexHealth>> indexHealthChangeListeners = new CopyOnWriteArrayList<>();
|
private final List<BiConsumer<ClusterIndexHealth, ClusterIndexHealth>> indexHealthChangeListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ public class IndexLifecycleManager extends AbstractComponent {
|
||||||
private volatile boolean mappingIsUpToDate;
|
private volatile boolean mappingIsUpToDate;
|
||||||
private volatile Version mappingVersion;
|
private volatile Version mappingVersion;
|
||||||
|
|
||||||
public IndexLifecycleManager(Settings settings, InternalClient client, String indexName, String templateName) {
|
public IndexLifecycleManager(Settings settings, InternalSecurityClient client, String indexName, String templateName) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.indexName = indexName;
|
this.indexName = indexName;
|
||||||
|
|
|
@ -184,6 +184,8 @@ public class User implements ToXContentObject {
|
||||||
return SystemUser.INSTANCE;
|
return SystemUser.INSTANCE;
|
||||||
} else if (XPackUser.is(username)) {
|
} else if (XPackUser.is(username)) {
|
||||||
return XPackUser.INSTANCE;
|
return XPackUser.INSTANCE;
|
||||||
|
} else if (XPackSecurityUser.is(username)) {
|
||||||
|
return XPackSecurityUser.INSTANCE;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("user [" + username + "] is not an internal user");
|
throw new IllegalStateException("user [" + username + "] is not an internal user");
|
||||||
}
|
}
|
||||||
|
@ -214,6 +216,9 @@ public class User implements ToXContentObject {
|
||||||
} else if (XPackUser.is(user)) {
|
} else if (XPackUser.is(user)) {
|
||||||
output.writeBoolean(true);
|
output.writeBoolean(true);
|
||||||
output.writeString(XPackUser.NAME);
|
output.writeString(XPackUser.NAME);
|
||||||
|
} else if (XPackSecurityUser.is(user)) {
|
||||||
|
output.writeBoolean(true);
|
||||||
|
output.writeString(XPackSecurityUser.NAME);
|
||||||
} else {
|
} else {
|
||||||
if (user.authenticatedUser == null) {
|
if (user.authenticatedUser == null) {
|
||||||
// no backcompat necessary, since there is no inner user
|
// no backcompat necessary, since there is no inner user
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* internal user that manages xpack security. Has all cluster/indices permissions.
|
||||||
|
*/
|
||||||
|
public class XPackSecurityUser extends User {
|
||||||
|
|
||||||
|
public static final String NAME = "_xpack_security";
|
||||||
|
public static final XPackSecurityUser INSTANCE = new XPackSecurityUser();
|
||||||
|
private static final String ROLE_NAME = "superuser";
|
||||||
|
|
||||||
|
private XPackSecurityUser() {
|
||||||
|
super(NAME, ROLE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return INSTANCE == o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return System.identityHashCode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean is(User user) {
|
||||||
|
return INSTANCE.equals(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean is(String principal) {
|
||||||
|
return NAME.equals(principal);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,22 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.user;
|
package org.elasticsearch.xpack.security.user;
|
||||||
|
|
||||||
|
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
||||||
|
import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
|
import org.elasticsearch.xpack.security.support.MetadataUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XPack internal user that manages xpack. Has all cluster/indices permissions for x-pack to operate.
|
* XPack internal user that manages xpack. Has all cluster/indices permissions for x-pack to operate excluding security permissions.
|
||||||
*/
|
*/
|
||||||
public class XPackUser extends User {
|
public class XPackUser extends User {
|
||||||
|
|
||||||
public static final String NAME = "_xpack";
|
public static final String NAME = "_xpack";
|
||||||
private static final String ROLE_NAME = "superuser";
|
public static final String ROLE_NAME = NAME;
|
||||||
|
public static final Role ROLE = Role.builder(new RoleDescriptor(ROLE_NAME, new String[] { "all" },
|
||||||
|
new RoleDescriptor.IndicesPrivileges[] {
|
||||||
|
RoleDescriptor.IndicesPrivileges.builder().indices("/@&~(\\.security*)/").privileges("all").build()},
|
||||||
|
new String[] { "*" },
|
||||||
|
MetadataUtils.DEFAULT_RESERVED_METADATA), null).build();
|
||||||
public static final XPackUser INSTANCE = new XPackUser();
|
public static final XPackUser INSTANCE = new XPackUser();
|
||||||
|
|
||||||
private XPackUser() {
|
private XPackUser() {
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.elasticsearch.xpack.upgrade;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||||
|
@ -24,6 +25,7 @@ import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeAction;
|
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeAction;
|
||||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction;
|
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction;
|
||||||
import org.elasticsearch.xpack.upgrade.rest.RestIndexUpgradeAction;
|
import org.elasticsearch.xpack.upgrade.rest.RestIndexUpgradeAction;
|
||||||
|
@ -53,12 +55,13 @@ public class Upgrade implements ActionPlugin {
|
||||||
this.upgradeCheckFactories = new ArrayList<>();
|
this.upgradeCheckFactories = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Object> createComponents(InternalClient internalClient, ClusterService clusterService, ThreadPool threadPool,
|
public Collection<Object> createComponents(Client client, ClusterService clusterService, ThreadPool threadPool,
|
||||||
ResourceWatcherService resourceWatcherService, ScriptService scriptService,
|
ResourceWatcherService resourceWatcherService, ScriptService scriptService,
|
||||||
NamedXContentRegistry xContentRegistry) {
|
NamedXContentRegistry xContentRegistry) {
|
||||||
|
final InternalSecurityClient internalSecurityClient = new InternalSecurityClient(settings, threadPool, client);
|
||||||
List<IndexUpgradeCheck> upgradeChecks = new ArrayList<>(upgradeCheckFactories.size());
|
List<IndexUpgradeCheck> upgradeChecks = new ArrayList<>(upgradeCheckFactories.size());
|
||||||
for (BiFunction<InternalClient, ClusterService, IndexUpgradeCheck> checkFactory : upgradeCheckFactories) {
|
for (BiFunction<InternalClient, ClusterService, IndexUpgradeCheck> checkFactory : upgradeCheckFactories) {
|
||||||
upgradeChecks.add(checkFactory.apply(internalClient, clusterService));
|
upgradeChecks.add(checkFactory.apply(internalSecurityClient, clusterService));
|
||||||
}
|
}
|
||||||
return Collections.singletonList(new IndexUpgradeService(settings, Collections.unmodifiableList(upgradeChecks)));
|
return Collections.singletonList(new IndexUpgradeService(settings, Collections.unmodifiableList(upgradeChecks)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.XPackSettings;
|
import org.elasticsearch.xpack.XPackSettings;
|
||||||
import org.elasticsearch.xpack.ml.MachineLearning;
|
import org.elasticsearch.xpack.ml.MachineLearning;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.Security;
|
import org.elasticsearch.xpack.security.Security;
|
||||||
import org.elasticsearch.xpack.security.client.SecurityClient;
|
import org.elasticsearch.xpack.security.client.SecurityClient;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -438,6 +439,11 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
|
||||||
return internalCluster().getInstance(InternalClient.class);
|
return internalCluster().getInstance(InternalClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InternalSecurityClient internalSecurityClient() {
|
||||||
|
Client client = client();
|
||||||
|
return new InternalSecurityClient(client.settings(), client.threadPool(), client);
|
||||||
|
}
|
||||||
|
|
||||||
protected SecurityClient securityClient() {
|
protected SecurityClient securityClient() {
|
||||||
return securityClient(client());
|
return securityClient(client());
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
||||||
|
|
||||||
threadPool = new TestThreadPool("security template service tests");
|
threadPool = new TestThreadPool("security template service tests");
|
||||||
transportClient = new MockTransportClient(Settings.EMPTY);
|
transportClient = new MockTransportClient(Settings.EMPTY);
|
||||||
class IClient extends InternalClient {
|
class IClient extends InternalSecurityClient {
|
||||||
IClient(Client transportClient) {
|
IClient(Client transportClient) {
|
||||||
super(Settings.EMPTY, null, transportClient);
|
super(Settings.EMPTY, null, transportClient);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalClient client = new IClient(transportClient);
|
InternalSecurityClient client = new IClient(transportClient);
|
||||||
securityLifecycleService = new SecurityLifecycleService(Settings.EMPTY, clusterService,
|
securityLifecycleService = new SecurityLifecycleService(Settings.EMPTY, clusterService,
|
||||||
threadPool, client, mock(IndexAuditTrail.class));
|
threadPool, client, mock(IndexAuditTrail.class));
|
||||||
listeners = new CopyOnWriteArrayList<>();
|
listeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
|
@ -77,9 +77,9 @@ public class SecurityTests extends ESTestCase {
|
||||||
allowedSettings.addAll(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
|
allowedSettings.addAll(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
|
||||||
ClusterSettings clusterSettings = new ClusterSettings(settings, allowedSettings);
|
ClusterSettings clusterSettings = new ClusterSettings(settings, allowedSettings);
|
||||||
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
|
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
|
||||||
InternalClient client = new InternalClient(Settings.EMPTY, threadPool, mock(Client.class));
|
|
||||||
when(threadPool.relativeTimeInMillis()).thenReturn(1L);
|
when(threadPool.relativeTimeInMillis()).thenReturn(1L);
|
||||||
return security.createComponents(client, threadPool, clusterService, mock(ResourceWatcherService.class), Arrays.asList(extensions));
|
return security.createComponents(mock(Client.class), threadPool, clusterService, mock(ResourceWatcherService.class),
|
||||||
|
Arrays.asList(extensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T findComponent(Class<T> type, Collection<Object> components) {
|
private <T> T findComponent(Class<T> type, Collection<Object> components) {
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class AuditTrailTests extends SecurityIntegTestCase {
|
||||||
return eventsRef.get();
|
return eventsRef.get();
|
||||||
}
|
}
|
||||||
private Collection<Map<String, Object>> getAuditEvents() throws Exception {
|
private Collection<Map<String, Object>> getAuditEvents() throws Exception {
|
||||||
final InternalClient client = internalClient();
|
final InternalClient client = internalSecurityClient();
|
||||||
DateTime now = new DateTime(DateTimeZone.UTC);
|
DateTime now = new DateTime(DateTimeZone.UTC);
|
||||||
String indexName = IndexNameResolver.resolve(IndexAuditTrail.INDEX_NAME_PREFIX, now, IndexNameResolver.Rollover.DAILY);
|
String indexName = IndexNameResolver.resolve(IndexAuditTrail.INDEX_NAME_PREFIX, now, IndexNameResolver.Rollover.DAILY);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.MockTransportClient;
|
import org.elasticsearch.transport.MockTransportClient;
|
||||||
import org.elasticsearch.transport.TransportMessage;
|
import org.elasticsearch.transport.TransportMessage;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail.State;
|
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail.State;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
|
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
|
||||||
import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule;
|
import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule;
|
||||||
|
@ -42,7 +43,7 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class IndexAuditTrailMutedTests extends ESTestCase {
|
public class IndexAuditTrailMutedTests extends ESTestCase {
|
||||||
|
|
||||||
private InternalClient client;
|
private InternalSecurityClient client;
|
||||||
private TransportClient transportClient;
|
private TransportClient transportClient;
|
||||||
private ThreadPool threadPool;
|
private ThreadPool threadPool;
|
||||||
private ClusterService clusterService;
|
private ClusterService clusterService;
|
||||||
|
@ -61,7 +62,7 @@ public class IndexAuditTrailMutedTests extends ESTestCase {
|
||||||
threadPool = new TestThreadPool("index audit trail tests");
|
threadPool = new TestThreadPool("index audit trail tests");
|
||||||
transportClient = new MockTransportClient(Settings.EMPTY);
|
transportClient = new MockTransportClient(Settings.EMPTY);
|
||||||
clientCalled = new AtomicBoolean(false);
|
clientCalled = new AtomicBoolean(false);
|
||||||
class IClient extends InternalClient {
|
class IClient extends InternalSecurityClient {
|
||||||
IClient(Client transportClient){
|
IClient(Client transportClient){
|
||||||
super(Settings.EMPTY, threadPool, transportClient);
|
super(Settings.EMPTY, threadPool, transportClient);
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
|
||||||
when(nodes.isLocalNodeElectedMaster()).thenReturn(true);
|
when(nodes.isLocalNodeElectedMaster()).thenReturn(true);
|
||||||
threadPool = new TestThreadPool("index audit trail tests");
|
threadPool = new TestThreadPool("index audit trail tests");
|
||||||
enqueuedMessage = new SetOnce<>();
|
enqueuedMessage = new SetOnce<>();
|
||||||
auditor = new IndexAuditTrail(settings, internalClient(), threadPool, clusterService) {
|
auditor = new IndexAuditTrail(settings, internalSecurityClient(), threadPool, clusterService) {
|
||||||
@Override
|
@Override
|
||||||
void enqueue(Message message, String type) {
|
void enqueue(Message message, String type) {
|
||||||
enqueuedMessage.set(message);
|
enqueuedMessage.set(message);
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class IndexAuditTrailUpdateMappingTests extends SecurityIntegTestCase {
|
||||||
when(localNode.getHostAddress()).thenReturn(buildNewFakeTransportAddress().toString());
|
when(localNode.getHostAddress()).thenReturn(buildNewFakeTransportAddress().toString());
|
||||||
ClusterService clusterService = mock(ClusterService.class);
|
ClusterService clusterService = mock(ClusterService.class);
|
||||||
when(clusterService.localNode()).thenReturn(localNode);
|
when(clusterService.localNode()).thenReturn(localNode);
|
||||||
auditor = new IndexAuditTrail(settings, internalClient(), threadPool, clusterService);
|
auditor = new IndexAuditTrail(settings, internalSecurityClient(), threadPool, clusterService);
|
||||||
|
|
||||||
// before starting we add an event
|
// before starting we add an event
|
||||||
auditor.authenticationFailed(new FakeRestRequest());
|
auditor.authenticationFailed(new FakeRestRequest());
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportMessage;
|
import org.elasticsearch.transport.TransportMessage;
|
||||||
import org.elasticsearch.xpack.XPackSettings;
|
import org.elasticsearch.xpack.XPackSettings;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
||||||
|
@ -135,7 +136,7 @@ public class AuthenticationServiceTests extends ESTestCase {
|
||||||
threadPool = new ThreadPool(settings,
|
threadPool = new ThreadPool(settings,
|
||||||
new FixedExecutorBuilder(settings, TokenService.THREAD_POOL_NAME, 1, 1000, "xpack.security.authc.token.thread_pool"));
|
new FixedExecutorBuilder(settings, TokenService.THREAD_POOL_NAME, 1, 1000, "xpack.security.authc.token.thread_pool"));
|
||||||
threadContext = threadPool.getThreadContext();
|
threadContext = threadPool.getThreadContext();
|
||||||
InternalClient internalClient = new InternalClient(Settings.EMPTY, threadPool, client);
|
InternalSecurityClient internalClient = new InternalSecurityClient(Settings.EMPTY, threadPool, client);
|
||||||
lifecycleService = mock(SecurityLifecycleService.class);
|
lifecycleService = mock(SecurityLifecycleService.class);
|
||||||
ClusterService clusterService = new ClusterService(settings, new ClusterSettings(settings, ClusterSettings
|
ClusterService clusterService = new ClusterService(settings, new ClusterSettings(settings, ClusterSettings
|
||||||
.BUILT_IN_CLUSTER_SETTINGS), threadPool, Collections.emptyMap());
|
.BUILT_IN_CLUSTER_SETTINGS), threadPool, Collections.emptyMap());
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class TokenAuthIntegTests extends SecurityIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTokenServiceBootstrapOnNodeJoin() throws Exception {
|
public void testTokenServiceBootstrapOnNodeJoin() throws Exception {
|
||||||
final Client client = internalClient();
|
final Client client = internalSecurityClient();
|
||||||
SecurityClient securityClient = new SecurityClient(client);
|
SecurityClient securityClient = new SecurityClient(client);
|
||||||
CreateTokenResponse response = securityClient.prepareCreateToken()
|
CreateTokenResponse response = securityClient.prepareCreateToken()
|
||||||
.setGrantType("password")
|
.setGrantType("password")
|
||||||
|
@ -84,7 +84,7 @@ public class TokenAuthIntegTests extends SecurityIntegTestCase {
|
||||||
|
|
||||||
|
|
||||||
public void testTokenServiceCanRotateKeys() throws Exception {
|
public void testTokenServiceCanRotateKeys() throws Exception {
|
||||||
final Client client = internalClient();
|
final Client client = internalSecurityClient();
|
||||||
SecurityClient securityClient = new SecurityClient(client);
|
SecurityClient securityClient = new SecurityClient(client);
|
||||||
CreateTokenResponse response = securityClient.prepareCreateToken()
|
CreateTokenResponse response = securityClient.prepareCreateToken()
|
||||||
.setGrantType("password")
|
.setGrantType("password")
|
||||||
|
@ -116,7 +116,7 @@ public class TokenAuthIntegTests extends SecurityIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExpiredTokensDeletedAfterExpiration() throws Exception {
|
public void testExpiredTokensDeletedAfterExpiration() throws Exception {
|
||||||
final Client client = internalClient();
|
final Client client = internalSecurityClient();
|
||||||
SecurityClient securityClient = new SecurityClient(client);
|
SecurityClient securityClient = new SecurityClient(client);
|
||||||
CreateTokenResponse response = securityClient.prepareCreateToken()
|
CreateTokenResponse response = securityClient.prepareCreateToken()
|
||||||
.setGrantType("password")
|
.setGrantType("password")
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.threadpool.FixedExecutorBuilder;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.XPackSettings;
|
import org.elasticsearch.xpack.XPackSettings;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
|
||||||
import org.elasticsearch.xpack.security.authc.TokenService.BytesKey;
|
import org.elasticsearch.xpack.security.authc.TokenService.BytesKey;
|
||||||
|
@ -49,7 +50,7 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class TokenServiceTests extends ESTestCase {
|
public class TokenServiceTests extends ESTestCase {
|
||||||
|
|
||||||
private InternalClient internalClient;
|
private InternalSecurityClient internalClient;
|
||||||
private static ThreadPool threadPool;
|
private static ThreadPool threadPool;
|
||||||
private static final Settings settings = Settings.builder().put(Node.NODE_NAME_SETTING.getKey(), "TokenServiceTests")
|
private static final Settings settings = Settings.builder().put(Node.NODE_NAME_SETTING.getKey(), "TokenServiceTests")
|
||||||
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true).build();
|
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true).build();
|
||||||
|
@ -63,7 +64,7 @@ public class TokenServiceTests extends ESTestCase {
|
||||||
@Before
|
@Before
|
||||||
public void setupClient() throws GeneralSecurityException {
|
public void setupClient() throws GeneralSecurityException {
|
||||||
client = mock(Client.class);
|
client = mock(Client.class);
|
||||||
internalClient = new InternalClient(settings, threadPool, client);
|
internalClient = new InternalSecurityClient(settings, threadPool, client);
|
||||||
lifecycleService = mock(SecurityLifecycleService.class);
|
lifecycleService = mock(SecurityLifecycleService.class);
|
||||||
when(lifecycleService.isSecurityIndexWriteable()).thenReturn(true);
|
when(lifecycleService.isSecurityIndexWriteable()).thenReturn(true);
|
||||||
doAnswer(invocationOnMock -> {
|
doAnswer(invocationOnMock -> {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.get.GetResult;
|
import org.elasticsearch.index.get.GetResult;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationResult;
|
import org.elasticsearch.xpack.security.authc.AuthenticationResult;
|
||||||
import org.elasticsearch.xpack.security.authc.support.Hasher;
|
import org.elasticsearch.xpack.security.authc.support.Hasher;
|
||||||
|
@ -54,12 +55,12 @@ public class NativeUsersStoreTests extends ESTestCase {
|
||||||
private static final String PASSWORD_FIELD = User.Fields.PASSWORD.getPreferredName();
|
private static final String PASSWORD_FIELD = User.Fields.PASSWORD.getPreferredName();
|
||||||
private static final String BLANK_PASSWORD = "";
|
private static final String BLANK_PASSWORD = "";
|
||||||
|
|
||||||
private InternalClient internalClient;
|
private InternalSecurityClient internalClient;
|
||||||
private final List<Tuple<ActionRequest, ActionListener<? extends ActionResponse>>> requests = new CopyOnWriteArrayList<>();
|
private final List<Tuple<ActionRequest, ActionListener<? extends ActionResponse>>> requests = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupMocks() {
|
public void setupMocks() {
|
||||||
internalClient = new InternalClient(Settings.EMPTY, null, null) {
|
internalClient = new InternalSecurityClient(Settings.EMPTY, null, null) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <
|
protected <
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.authc.RealmConfig;
|
import org.elasticsearch.xpack.security.authc.RealmConfig;
|
||||||
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
|
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
|
||||||
|
@ -53,7 +54,7 @@ public class NativeUserRoleMapperTests extends ESTestCase {
|
||||||
Collections.singletonList(FieldPredicate.create("cn=mutants,ou=groups,ou=dept_h,o=forces,dc=gc,dc=ca"))),
|
Collections.singletonList(FieldPredicate.create("cn=mutants,ou=groups,ou=dept_h,o=forces,dc=gc,dc=ca"))),
|
||||||
Arrays.asList("mutants"), Collections.emptyMap(), false);
|
Arrays.asList("mutants"), Collections.emptyMap(), false);
|
||||||
|
|
||||||
final InternalClient client = mock(InternalClient.class);
|
final InternalSecurityClient client = mock(InternalSecurityClient.class);
|
||||||
final SecurityLifecycleService lifecycleService = mock(SecurityLifecycleService.class);
|
final SecurityLifecycleService lifecycleService = mock(SecurityLifecycleService.class);
|
||||||
when(lifecycleService.isSecurityIndexAvailable()).thenReturn(true);
|
when(lifecycleService.isSecurityIndexAvailable()).thenReturn(true);
|
||||||
|
|
||||||
|
|
|
@ -715,7 +715,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testXPackUserAndSuperusersCanExecuteOperationAgainstSecurityIndex() {
|
public void testSuperusersCanExecuteOperationAgainstSecurityIndex() {
|
||||||
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
|
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
|
||||||
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
|
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
|
||||||
ClusterState state = mock(ClusterState.class);
|
ClusterState state = mock(ClusterState.class);
|
||||||
|
@ -726,37 +726,35 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
.numberOfShards(1).numberOfReplicas(0).build(), true)
|
.numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
for (User user : Arrays.asList(XPackUser.INSTANCE, superuser)) {
|
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
|
||||||
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
|
requests.add(new Tuple<>(DeleteAction.NAME, new DeleteRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
||||||
requests.add(new Tuple<>(DeleteAction.NAME, new DeleteRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
|
||||||
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
|
createBulkShardRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, DeleteRequest::new)));
|
||||||
createBulkShardRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, DeleteRequest::new)));
|
requests.add(new Tuple<>(UpdateAction.NAME, new UpdateRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
||||||
requests.add(new Tuple<>(UpdateAction.NAME, new UpdateRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
requests.add(new Tuple<>(IndexAction.NAME, new IndexRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
||||||
requests.add(new Tuple<>(IndexAction.NAME, new IndexRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
|
||||||
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
|
createBulkShardRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, IndexRequest::new)));
|
||||||
createBulkShardRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, IndexRequest::new)));
|
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(SecurityLifecycleService.SECURITY_INDEX_NAME)));
|
||||||
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(SecurityLifecycleService.SECURITY_INDEX_NAME)));
|
requests.add(new Tuple<>(TermVectorsAction.NAME,
|
||||||
requests.add(new Tuple<>(TermVectorsAction.NAME,
|
new TermVectorsRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
||||||
new TermVectorsRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
||||||
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
requests.add(new Tuple<>(TermVectorsAction.NAME,
|
||||||
requests.add(new Tuple<>(TermVectorsAction.NAME,
|
new TermVectorsRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
||||||
new TermVectorsRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "type", "id")));
|
requests.add(new Tuple<>(IndicesAliasesAction.NAME, new IndicesAliasesRequest()
|
||||||
requests.add(new Tuple<>(IndicesAliasesAction.NAME, new IndicesAliasesRequest()
|
.addAliasAction(AliasActions.add().alias("security_alias").index(SecurityLifecycleService.SECURITY_INDEX_NAME))));
|
||||||
.addAliasAction(AliasActions.add().alias("security_alias").index(SecurityLifecycleService.SECURITY_INDEX_NAME))));
|
requests.add(new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(SecurityLifecycleService.SECURITY_INDEX_NAME)));
|
||||||
requests.add(new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(SecurityLifecycleService.SECURITY_INDEX_NAME)));
|
requests.add(new Tuple<>(ClusterHealthAction.NAME,
|
||||||
requests.add(new Tuple<>(ClusterHealthAction.NAME,
|
new ClusterHealthRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "foo", "bar")));
|
||||||
new ClusterHealthRequest(SecurityLifecycleService.SECURITY_INDEX_NAME, "foo", "bar")));
|
|
||||||
|
|
||||||
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();
|
||||||
authorize(createAuthentication(user), action, request);
|
authorize(createAuthentication(superuser), action, request);
|
||||||
verify(auditTrail).accessGranted(user, action, request);
|
verify(auditTrail).accessGranted(superuser, action, request);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testXPackUserAndSuperusersCanExecuteOperationAgainstSecurityIndexWithWildcard() {
|
public void testSuperusersCanExecuteOperationAgainstSecurityIndexWithWildcard() {
|
||||||
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
|
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
|
||||||
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
|
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
|
||||||
ClusterState state = mock(ClusterState.class);
|
ClusterState state = mock(ClusterState.class);
|
||||||
|
@ -769,11 +767,6 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
String action = SearchAction.NAME;
|
String action = SearchAction.NAME;
|
||||||
SearchRequest request = new SearchRequest("_all");
|
SearchRequest request = new SearchRequest("_all");
|
||||||
authorize(createAuthentication(XPackUser.INSTANCE), action, request);
|
|
||||||
verify(auditTrail).accessGranted(XPackUser.INSTANCE, action, request);
|
|
||||||
assertThat(request.indices(), arrayContaining(".security"));
|
|
||||||
|
|
||||||
request = new SearchRequest("_all");
|
|
||||||
authorize(createAuthentication(superuser), action, request);
|
authorize(createAuthentication(superuser), action, request);
|
||||||
verify(auditTrail).accessGranted(superuser, action, request);
|
verify(auditTrail).accessGranted(superuser, action, request);
|
||||||
assertThat(request.indices(), arrayContaining(".security"));
|
assertThat(request.indices(), arrayContaining(".security"));
|
||||||
|
@ -1073,7 +1066,7 @@ public class AuthorizationServiceTests extends ESTestCase {
|
||||||
PlainActionFuture<Role> rolesFuture = new PlainActionFuture<>();
|
PlainActionFuture<Role> rolesFuture = new PlainActionFuture<>();
|
||||||
authorizationService.roles(XPackUser.INSTANCE, rolesFuture);
|
authorizationService.roles(XPackUser.INSTANCE, rolesFuture);
|
||||||
final Role roles = rolesFuture.actionGet();
|
final Role roles = rolesFuture.actionGet();
|
||||||
assertThat(roles, equalTo(ReservedRolesStore.SUPERUSER_ROLE));
|
assertThat(roles, equalTo(XPackUser.ROLE));
|
||||||
verifyZeroInteractions(rolesStore);
|
verifyZeroInteractions(rolesStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ import org.elasticsearch.xpack.security.authz.store.ReservedRolesStore;
|
||||||
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
|
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
|
||||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||||
import org.elasticsearch.xpack.security.user.User;
|
import org.elasticsearch.xpack.security.user.User;
|
||||||
|
import org.elasticsearch.xpack.security.user.XPackSecurityUser;
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -1191,22 +1192,29 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testXPackUserHasAccessToSecurityIndex() {
|
public void testXPackSecurityUserHasAccessToSecurityIndex() {
|
||||||
SearchRequest request = new SearchRequest();
|
SearchRequest request = new SearchRequest();
|
||||||
{
|
{
|
||||||
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackUser.INSTANCE, SearchAction.NAME);
|
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackSecurityUser.INSTANCE, SearchAction.NAME);
|
||||||
List<String> indices = resolveIndices(request, authorizedIndices).getLocal();
|
List<String> indices = resolveIndices(request, authorizedIndices).getLocal();
|
||||||
assertThat(indices, hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME));
|
assertThat(indices, hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest();
|
IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest();
|
||||||
aliasesRequest.addAliasAction(AliasActions.add().alias("security_alias").index(SecurityLifecycleService.SECURITY_INDEX_NAME));
|
aliasesRequest.addAliasAction(AliasActions.add().alias("security_alias").index(SecurityLifecycleService.SECURITY_INDEX_NAME));
|
||||||
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackUser.INSTANCE, IndicesAliasesAction.NAME);
|
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackSecurityUser.INSTANCE, IndicesAliasesAction.NAME);
|
||||||
List<String> indices = resolveIndices(aliasesRequest, authorizedIndices).getLocal();
|
List<String> indices = resolveIndices(aliasesRequest, authorizedIndices).getLocal();
|
||||||
assertThat(indices, hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME));
|
assertThat(indices, hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testXPackUserDoesNotHaveAccessToSecurityIndex() {
|
||||||
|
SearchRequest request = new SearchRequest();
|
||||||
|
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackUser.INSTANCE, SearchAction.NAME);
|
||||||
|
List<String> indices = resolveIndices(request, authorizedIndices).getLocal();
|
||||||
|
assertThat(indices, not(hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME)));
|
||||||
|
}
|
||||||
|
|
||||||
public void testNonXPackUserAccessingSecurityIndex() {
|
public void testNonXPackUserAccessingSecurityIndex() {
|
||||||
User allAccessUser = new User("all_access", "all_access");
|
User allAccessUser = new User("all_access", "all_access");
|
||||||
roleMap.put("all_access", new RoleDescriptor("all_access", new String[] { "all" },
|
roleMap.put("all_access", new RoleDescriptor("all_access", new String[] { "all" },
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.security.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||||
import org.elasticsearch.xpack.security.action.role.PutRoleRequest;
|
import org.elasticsearch.xpack.security.action.role.PutRoleRequest;
|
||||||
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
||||||
|
@ -184,7 +185,7 @@ public class NativeRolesStoreTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPutOfRoleWithFlsDlsUnlicensed() throws IOException {
|
public void testPutOfRoleWithFlsDlsUnlicensed() throws IOException {
|
||||||
final InternalClient internalClient = mock(InternalClient.class);
|
final InternalSecurityClient internalClient = mock(InternalSecurityClient.class);
|
||||||
final ClusterService clusterService = mock(ClusterService.class);
|
final ClusterService clusterService = mock(ClusterService.class);
|
||||||
final XPackLicenseState licenseState = mock(XPackLicenseState.class);
|
final XPackLicenseState licenseState = mock(XPackLicenseState.class);
|
||||||
final AtomicBoolean methodCalled = new AtomicBoolean(false);
|
final AtomicBoolean methodCalled = new AtomicBoolean(false);
|
||||||
|
|
|
@ -80,6 +80,7 @@ import org.elasticsearch.xpack.security.authz.accesscontrol.IndicesAccessControl
|
||||||
import org.elasticsearch.xpack.security.authz.permission.FieldPermissionsCache;
|
import org.elasticsearch.xpack.security.authz.permission.FieldPermissionsCache;
|
||||||
import org.elasticsearch.xpack.security.authz.permission.Role;
|
import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||||
import org.elasticsearch.xpack.security.user.SystemUser;
|
import org.elasticsearch.xpack.security.user.SystemUser;
|
||||||
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
import org.elasticsearch.xpack.watcher.execution.TriggeredWatchStore;
|
import org.elasticsearch.xpack.watcher.execution.TriggeredWatchStore;
|
||||||
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
||||||
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchAction;
|
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchAction;
|
||||||
|
@ -123,6 +124,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(ReservedRolesStore.isReserved("watcher_user"), is(true));
|
assertThat(ReservedRolesStore.isReserved("watcher_user"), is(true));
|
||||||
assertThat(ReservedRolesStore.isReserved("watcher_admin"), is(true));
|
assertThat(ReservedRolesStore.isReserved("watcher_admin"), is(true));
|
||||||
assertThat(ReservedRolesStore.isReserved("kibana_dashboard_only_user"), is(true));
|
assertThat(ReservedRolesStore.isReserved("kibana_dashboard_only_user"), is(true));
|
||||||
|
assertThat(ReservedRolesStore.isReserved(XPackUser.ROLE_NAME), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIngestAdminRole() {
|
public void testIngestAdminRole() {
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.elasticsearch.index.shard.ShardId;
|
||||||
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.InternalClient;
|
import org.elasticsearch.xpack.security.InternalClient;
|
||||||
|
import org.elasticsearch.xpack.security.InternalSecurityClient;
|
||||||
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
|
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
|
||||||
import org.elasticsearch.xpack.template.TemplateUtils;
|
import org.elasticsearch.xpack.template.TemplateUtils;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
@ -71,7 +72,7 @@ public class IndexLifecycleManagerTests extends ESTestCase {
|
||||||
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
|
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
|
||||||
|
|
||||||
actions = new LinkedHashMap<>();
|
actions = new LinkedHashMap<>();
|
||||||
final InternalClient client = new InternalClient(Settings.EMPTY, threadPool, mockClient) {
|
final InternalSecurityClient client = new InternalSecurityClient(Settings.EMPTY, threadPool, mockClient) {
|
||||||
@Override
|
@Override
|
||||||
protected <Request extends ActionRequest,
|
protected <Request extends ActionRequest,
|
||||||
Response extends ActionResponse,
|
Response extends ActionResponse,
|
||||||
|
|
Loading…
Reference in New Issue