Remove implicit index monitor privilege (#37774)

Restricted indices (currently only .security-6 and .security) are special
internal indices that require setting the `allow_restricted_indices` flag
on every index permission that covers them. If this flag is `false`
(default) the permission will not cover these and actions against them
will not be authorized.
However, the monitoring APIs were the only exception to this rule.

This exception is herein forfeited and index monitoring privileges have to be
granted explicitly, using the `allow_restricted_indices` flag on the permission,
as is the case for any other index privilege.
This commit is contained in:
Albert Zaharovits 2019-01-29 21:10:03 +02:00 committed by GitHub
parent 34d61d3231
commit 697b2fbe52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 232 additions and 67 deletions

View File

@ -126,3 +126,15 @@ removed.
The `_termvector` endpoint was deprecated in 2.0 and has now been removed.
The endpoint `_termvectors` (plural) should be used instead.
[float]
==== When {security-features} are enabled, index monitoring APIs over restricted indices are not authorized implicitly anymore
Restricted indices (currently only `.security-6` and `.security`) are special internal
indices that require setting the `allow_restricted_indices` flag on every index
permission that covers them. If this flag is `false` (default) the permission
will not cover these and actions against them will not be authorized.
However, the monitoring APIs were the only exception to this rule. This exception
has been forfeited and index monitoring privileges have to be granted explicitly,
using the `allow_restricted_indices` flag on the permission (as any other index
privilege).

View File

@ -259,12 +259,8 @@ public final class IndicesPermission {
private boolean check(String action, String index) {
assert index != null;
return check(action) && (indexNameMatcher.test(index)
&& (allowRestrictedIndices
// all good if it is not restricted
|| (false == RestrictedIndicesNames.NAMES_SET.contains(index))
// allow monitor as a special case, even for restricted
|| IndexPrivilege.MONITOR.predicate().test(action)));
return check(action) && indexNameMatcher.test(index)
&& (allowRestrictedIndices || (false == RestrictedIndicesNames.NAMES_SET.contains(index)));
}
boolean hasQuery() {

View File

@ -144,6 +144,7 @@ import org.joda.time.DateTimeZone;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.hasEntry;
@ -563,9 +564,33 @@ public class ReservedRolesStoreTests extends ESTestCase {
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndexAction.NAME)
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(false));
assertMonitoringOnRestrictedIndices(remoteMonitoringAgentRole);
assertNoAccessAllowed(remoteMonitoringAgentRole, RestrictedIndicesNames.NAMES_SET);
}
private void assertMonitoringOnRestrictedIndices(Role role) {
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
final MetaData metaData = new MetaData.Builder()
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
.settings(indexSettings)
.numberOfShards(1)
.numberOfReplicas(0)
.putAlias(new AliasMetaData.Builder(RestrictedIndicesNames.SECURITY_INDEX_NAME).build())
.build(), true)
.build();
final FieldPermissionsCache fieldPermissionsCache = new FieldPermissionsCache(Settings.EMPTY);
final List<String> indexMonitoringActionNamesList = Arrays.asList(IndicesStatsAction.NAME, IndicesSegmentsAction.NAME,
GetSettingsAction.NAME, IndicesShardStoresAction.NAME, UpgradeStatusAction.NAME, RecoveryAction.NAME);
for (final String indexMonitoringActionName : indexMonitoringActionNamesList) {
final Map<String, IndexAccessControl> authzMap = role.indices().authorize(indexMonitoringActionName,
Sets.newHashSet(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME), metaData,
fieldPermissionsCache);
assertThat(authzMap.get(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX).isGranted(), is(true));
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
}
}
public void testReportingUserRole() {
final TransportRequest request = mock(TransportRequest.class);

View File

@ -7,14 +7,27 @@ package org.elasticsearch.integration;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse;
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentResponse;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresResponse;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.admin.indices.upgrade.get.UpgradeStatusResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.junit.After;
import org.junit.Before;
import java.util.Collections;
@ -25,11 +38,29 @@ import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswo
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.containsInAnyOrder;
public class MultipleIndicesPermissionsTests extends SecurityIntegTestCase {
protected static final SecureString USERS_PASSWD = new SecureString("passwd".toCharArray());
@Before
public void waitForSecurityIndexWritable() throws Exception {
// adds a dummy user to the native realm to force .security index creation
securityClient().preparePutUser("dummy_user", "password".toCharArray(), Hasher.BCRYPT, "missing_role").get();
assertSecurityIndexActive();
}
@After
public void cleanupSecurityIndex() throws Exception {
super.deleteSecurityIndex();
}
@Override
protected boolean addMockHttpTransport() {
return false; // enable http
}
@Override
protected String configRoles() {
return SecuritySettingsSource.TEST_ROLE + ":\n" +
@ -49,6 +80,12 @@ public class MultipleIndicesPermissionsTests extends SecurityIntegTestCase {
" - names: 'a'\n" +
" privileges: [all]\n" +
"\n" +
"role_monitor_all_unrestricted_indices:\n" +
" cluster: [monitor]\n" +
" indices:\n" +
" - names: '*'\n" +
" privileges: [monitor]\n" +
"\n" +
"role_b:\n" +
" indices:\n" +
" - names: 'b'\n" +
@ -60,14 +97,16 @@ public class MultipleIndicesPermissionsTests extends SecurityIntegTestCase {
final String usersPasswdHashed = new String(getFastStoredHashAlgoForTests().hash(USERS_PASSWD));
return SecuritySettingsSource.CONFIG_STANDARD_USER +
"user_a:" + usersPasswdHashed + "\n" +
"user_ab:" + usersPasswdHashed + "\n";
"user_ab:" + usersPasswdHashed + "\n" +
"user_monitor:" + usersPasswdHashed + "\n";
}
@Override
protected String configUsersRoles() {
return SecuritySettingsSource.CONFIG_STANDARD_USER_ROLES +
"role_a:user_a,user_ab\n" +
"role_b:user_ab\n";
"role_b:user_ab\n" +
"role_monitor_all_unrestricted_indices:user_monitor\n";
}
public void testSingleRole() throws Exception {
@ -127,6 +166,71 @@ public class MultipleIndicesPermissionsTests extends SecurityIntegTestCase {
assertHitCount(searchResponse, 1);
}
public void testMonitorRestrictedWildcards() throws Exception {
IndexResponse indexResponse = index("foo", "type", jsonBuilder()
.startObject()
.field("name", "value")
.endObject());
assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult());
indexResponse = index("foobar", "type", jsonBuilder()
.startObject()
.field("name", "value")
.endObject());
assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult());
indexResponse = index("foobarfoo", "type", jsonBuilder()
.startObject()
.field("name", "value")
.endObject());
assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult());
refresh();
final Client client = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_monitor", USERS_PASSWD)));
final GetSettingsResponse getSettingsResponse = client.admin().indices().prepareGetSettings(randomFrom("*", "_all", "foo*")).get();
assertThat(getSettingsResponse.getIndexToSettings().size(), is(3));
assertThat(getSettingsResponse.getIndexToSettings().containsKey("foo"), is(true));
assertThat(getSettingsResponse.getIndexToSettings().containsKey("foobar"), is(true));
assertThat(getSettingsResponse.getIndexToSettings().containsKey("foobarfoo"), is(true));
final IndicesShardStoresResponse indicesShardsStoresResponse = client.admin().indices()
.prepareShardStores(randomFrom("*", "_all", "foo*")).setShardStatuses("all").get();
assertThat(indicesShardsStoresResponse.getStoreStatuses().size(), is(3));
assertThat(indicesShardsStoresResponse.getStoreStatuses().containsKey("foo"), is(true));
assertThat(indicesShardsStoresResponse.getStoreStatuses().containsKey("foobar"), is(true));
assertThat(indicesShardsStoresResponse.getStoreStatuses().containsKey("foobarfoo"), is(true));
final UpgradeStatusResponse upgradeStatusResponse = client.admin().indices().prepareUpgradeStatus(randomFrom("*", "_all", "foo*"))
.get();
assertThat(upgradeStatusResponse.getIndices().size(), is(3));
assertThat(upgradeStatusResponse.getIndices().keySet(), containsInAnyOrder("foo", "foobar", "foobarfoo"));
final IndicesStatsResponse indicesStatsResponse = client.admin().indices().prepareStats(randomFrom("*", "_all", "foo*")).get();
assertThat(indicesStatsResponse.getIndices().size(), is(3));
assertThat(indicesStatsResponse.getIndices().keySet(), containsInAnyOrder("foo", "foobar", "foobarfoo"));
final IndicesSegmentResponse indicesSegmentResponse = client.admin().indices().prepareSegments("*").get();
assertThat(indicesSegmentResponse.getIndices().size(), is(3));
assertThat(indicesSegmentResponse.getIndices().keySet(), containsInAnyOrder("foo", "foobar", "foobarfoo"));
final RecoveryResponse indicesRecoveryResponse = client.admin().indices().prepareRecoveries("*").get();
assertThat(indicesRecoveryResponse.shardRecoveryStates().size(), is(3));
assertThat(indicesRecoveryResponse.shardRecoveryStates().keySet(), containsInAnyOrder("foo", "foobar", "foobarfoo"));
// test _cat/indices with wildcards that cover unauthorized indices (".security" in this case)
RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
optionsBuilder.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue("user_monitor", USERS_PASSWD));
RequestOptions options = optionsBuilder.build();
Request catIndicesRequest = new Request("GET", "/_cat/indices/" + randomFrom("*", "_all", "foo*"));
catIndicesRequest.setOptions(options);
Response catIndicesResponse = getRestClient().performRequest(catIndicesRequest);
assertThat(catIndicesResponse.getStatusLine().getStatusCode() < 300, is(true));
}
public void testMultipleRoles() throws Exception {
IndexResponse indexResponse = index("a", "type", jsonBuilder()
.startObject()

View File

@ -78,6 +78,7 @@ public class SecuritySettingsSource extends NodeConfigurationSource {
" cluster: [ ALL ]\n" +
" indices:\n" +
" - names: '*'\n" +
" allow_restricted_indices: true\n" +
" privileges: [ ALL ]\n";
private final Path parentFolder;

View File

@ -73,6 +73,7 @@ import org.elasticsearch.action.update.UpdateAction;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
@ -151,7 +152,8 @@ import static org.elasticsearch.test.SecurityTestsUtils.assertAuthenticationExce
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationExceptionRunAs;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.hamcrest.Matchers.arrayContaining;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_SECURITY_INDEX;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
@ -804,7 +806,7 @@ public class AuthorizationServiceTests extends ESTestCase {
verifyNoMoreInteractions(auditTrail);
}
public void testNonXPackUserCannotExecuteOperationAgainstSecurityIndex() {
public void testGrantAllRestrictedUserCannotExecuteOperationAgainstSecurityIndices() {
RoleDescriptor role = new RoleDescriptor("all access", new String[]{"all"},
new IndicesPrivileges[]{IndicesPrivileges.builder().indices("*").privileges("all").build()}, null);
final Authentication authentication = createAuthentication(new User("all_access_user", "all_access"));
@ -812,29 +814,41 @@ public class AuthorizationServiceTests extends ESTestCase {
ClusterState state = mock(ClusterState.class);
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.builder()
.put(new IndexMetaData.Builder(SECURITY_INDEX_NAME)
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder(INTERNAL_SECURITY_INDEX)
.putAlias(new AliasMetaData.Builder(SECURITY_INDEX_NAME).build())
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1)
.numberOfReplicas(0)
.build(),true)
.build());
final String requestId = AuditUtil.getOrGenerateRequestId(threadContext);
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
new DeleteRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(UpdateAction.NAME,
new UpdateRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
new IndexRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(IndicesAliasesAction.NAME, new IndicesAliasesRequest()
.addAliasAction(AliasActions.add().alias("security_alias").index(SECURITY_INDEX_NAME))));
requests.add(
new Tuple<>(UpdateSettingsAction.NAME, new UpdateSettingsRequest().indices(SECURITY_INDEX_NAME)));
new Tuple<>(BulkAction.NAME + "[s]", new DeleteRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "id")));
requests.add(new Tuple<>(UpdateAction.NAME, new UpdateRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]", new IndexRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "type", "id")));
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "id")));
requests.add(new Tuple<>(IndicesAliasesAction.NAME, new IndicesAliasesRequest()
.addAliasAction(AliasActions.add().alias("security_alias").index(INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(UpdateSettingsAction.NAME,
new UpdateSettingsRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
// cannot execute monitor operations
requests.add(new Tuple<>(IndicesStatsAction.NAME,
new IndicesStatsRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(
new Tuple<>(RecoveryAction.NAME, new RecoveryRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(IndicesSegmentsAction.NAME,
new IndicesSegmentsRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(GetSettingsAction.NAME,
new GetSettingsRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(IndicesShardStoresAction.NAME,
new IndicesShardStoresRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(UpgradeStatusAction.NAME,
new UpgradeStatusRequest().indices(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
for (Tuple<String, TransportRequest> requestTuple : requests) {
String action = requestTuple.v1();
@ -847,12 +861,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
ClusterHealthRequest request = new ClusterHealthRequest(SECURITY_INDEX_NAME);
ClusterHealthRequest request = new ClusterHealthRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX));
authorize(authentication, ClusterHealthAction.NAME, request);
verify(auditTrail).accessGranted(requestId, authentication, ClusterHealthAction.NAME, request, new String[]{role.getName()});
// multiple indices
request = new ClusterHealthRequest(SECURITY_INDEX_NAME, "foo", "bar");
request = new ClusterHealthRequest(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX, "foo", "bar");
authorize(authentication, ClusterHealthAction.NAME, request);
verify(auditTrail).accessGranted(requestId, authentication, ClusterHealthAction.NAME, request, new String[]{role.getName()});
verifyNoMoreInteractions(auditTrail);
@ -863,17 +877,24 @@ public class AuthorizationServiceTests extends ESTestCase {
assertEquals(IndicesAndAliasesResolver.NO_INDICES_OR_ALIASES_LIST, Arrays.asList(searchRequest.indices()));
}
public void testGrantedNonXPackUserCanExecuteMonitoringOperationsAgainstSecurityIndex() {
RoleDescriptor role = new RoleDescriptor("all access", new String[]{"all"},
new IndicesPrivileges[]{IndicesPrivileges.builder().indices("*").privileges("all").build()}, null);
final Authentication authentication = createAuthentication(new User("all_access_user", "all_access"));
roleMap.put("all_access", role);
public void testMonitoringOperationsAgainstSecurityIndexRequireAllowRestricted() {
final RoleDescriptor restrictedMonitorRole = new RoleDescriptor("restricted_monitor", null,
new IndicesPrivileges[] { IndicesPrivileges.builder().indices("*").privileges("monitor").build() }, null);
final RoleDescriptor unrestrictedMonitorRole = new RoleDescriptor("unrestricted_monitor", null, new IndicesPrivileges[] {
IndicesPrivileges.builder().indices("*").privileges("monitor").allowRestrictedIndices(true).build() }, null);
roleMap.put("restricted_monitor", restrictedMonitorRole);
roleMap.put("unrestricted_monitor", unrestrictedMonitorRole);
final Authentication restrictedUserAuthn = createAuthentication(new User("restricted_user", "restricted_monitor"));
final Authentication unrestrictedUserAuthn = createAuthentication(new User("unrestricted_user", "unrestricted_monitor"));
ClusterState state = mock(ClusterState.class);
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.builder()
.put(new IndexMetaData.Builder(SECURITY_INDEX_NAME)
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder(INTERNAL_SECURITY_INDEX)
.putAlias(new AliasMetaData.Builder(SECURITY_INDEX_NAME).build())
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1)
.numberOfReplicas(0)
.build(), true)
.build());
final String requestId = AuditUtil.getOrGenerateRequestId(threadContext);
@ -882,16 +903,18 @@ public class AuthorizationServiceTests extends ESTestCase {
requests.add(new Tuple<>(RecoveryAction.NAME, new RecoveryRequest().indices(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(IndicesSegmentsAction.NAME, new IndicesSegmentsRequest().indices(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(GetSettingsAction.NAME, new GetSettingsRequest().indices(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(IndicesShardStoresAction.NAME,
new IndicesShardStoresRequest().indices(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(UpgradeStatusAction.NAME,
new UpgradeStatusRequest().indices(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(IndicesShardStoresAction.NAME, new IndicesShardStoresRequest().indices(SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(UpgradeStatusAction.NAME, new UpgradeStatusRequest().indices(SECURITY_INDEX_NAME)));
for (final Tuple<String, ? extends TransportRequest> requestTuple : requests) {
final String action = requestTuple.v1();
final TransportRequest request = requestTuple.v2();
authorize(authentication, action, request);
verify(auditTrail).accessGranted(requestId, authentication, action, request, new String[]{role.getName()});
assertThrowsAuthorizationException(() -> authorize(restrictedUserAuthn, action, request), action, "restricted_user");
verify(auditTrail).accessDenied(requestId, restrictedUserAuthn, action, request, new String[] { "restricted_monitor" });
verifyNoMoreInteractions(auditTrail);
authorize(unrestrictedUserAuthn, action, request);
verify(auditTrail).accessGranted(requestId, unrestrictedUserAuthn, action, request, new String[] { "unrestricted_monitor" });
verifyNoMoreInteractions(auditTrail);
}
}
@ -901,34 +924,35 @@ public class AuthorizationServiceTests extends ESTestCase {
ClusterState state = mock(ClusterState.class);
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.builder()
.put(new IndexMetaData.Builder(SECURITY_INDEX_NAME)
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder(INTERNAL_SECURITY_INDEX)
.putAlias(new AliasMetaData.Builder(SECURITY_INDEX_NAME).build())
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1)
.numberOfReplicas(0)
.build(), true)
.build());
final String requestId = AuditUtil.getOrGenerateRequestId(threadContext);
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
requests.add(new Tuple<>(DeleteAction.NAME,
new DeleteRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(DeleteAction.NAME, new DeleteRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
createBulkShardRequest(SECURITY_INDEX_NAME, DeleteRequest::new)));
requests.add(new Tuple<>(UpdateAction.NAME,
new UpdateRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(IndexAction.NAME,
new IndexRequest(SECURITY_INDEX_NAME, "type", "id")));
createBulkShardRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), DeleteRequest::new)));
requests.add(new Tuple<>(UpdateAction.NAME, new UpdateRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "id")));
requests.add(new Tuple<>(IndexAction.NAME, new IndexRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
createBulkShardRequest(SECURITY_INDEX_NAME, IndexRequest::new)));
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(SECURITY_INDEX_NAME)));
createBulkShardRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), IndexRequest::new)));
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(SECURITY_INDEX_NAME, "type", "id")));
new TermVectorsRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "type", "id")));
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "type", "id")));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(IndicesAliasesAction.NAME, new IndicesAliasesRequest()
.addAliasAction(AliasActions.add().alias("security_alias").index(SECURITY_INDEX_NAME))));
requests.add(new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(SECURITY_INDEX_NAME)));
new TermVectorsRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "type", "id")));
requests.add(new Tuple<>(IndicesAliasesAction.NAME,
new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("security_alias").index(INTERNAL_SECURITY_INDEX))));
requests.add(
new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX))));
requests.add(new Tuple<>(ClusterHealthAction.NAME,
new ClusterHealthRequest(SECURITY_INDEX_NAME, "foo", "bar")));
new ClusterHealthRequest(randomFrom(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX), "foo", "bar")));
for (final Tuple<String, TransportRequest> requestTuple : requests) {
final String action = requestTuple.v1();
@ -946,9 +970,12 @@ public class AuthorizationServiceTests extends ESTestCase {
ClusterState state = mock(ClusterState.class);
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.builder()
.put(new IndexMetaData.Builder(SECURITY_INDEX_NAME)
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder(INTERNAL_SECURITY_INDEX)
.putAlias(new AliasMetaData.Builder(SECURITY_INDEX_NAME).build())
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
.numberOfShards(1)
.numberOfReplicas(0)
.build(), true)
.build());
final String requestId = AuditUtil.getOrGenerateRequestId(threadContext);
@ -956,7 +983,7 @@ public class AuthorizationServiceTests extends ESTestCase {
SearchRequest request = new SearchRequest("_all");
authorize(createAuthentication(superuser), action, request);
verify(auditTrail).accessGranted(requestId, authentication, action, request, superuser.roles());
assertThat(request.indices(), arrayContaining(".security"));
assertThat(request.indices(), arrayContainingInAnyOrder(INTERNAL_SECURITY_INDEX, SECURITY_INDEX_NAME));
}
public void testAnonymousRolesAreAppliedToOtherUsers() {