Backport: Deprecate the kibana reserved user (#54967) (#55822)

This commit is contained in:
Larry Gregory 2020-04-28 10:30:25 -04:00 committed by GitHub
parent ddc7305ac9
commit 47d252424b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 284 additions and 112 deletions

View File

@ -198,10 +198,11 @@ public class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
List<User> users = new ArrayList<>(3);
users.addAll(response.getUsers());
assertNotNull(response);
// 9 users are expected to be returned
// 10 users are expected to be returned
// test_users (3): user1, user2, user3
// system_users (6): elastic, beats_system, apm_system, logstash_system, kibana, remote_monitoring_user
assertThat(users.size(), equalTo(9));
// system_users (6): elastic, beats_system, apm_system, logstash_system, kibana, kibana_system, remote_monitoring_user
logger.info(users);
assertThat(users.size(), equalTo(10));
}
{

View File

@ -92,4 +92,40 @@ To avoid deprecation warnings, discontinue use of the `node.local_storage`
setting.
====
//end::notable-breaking-changes[]
[float]
[[builtin-users-changes]]
==== Changes to built-in users
[float]
===== The `kibana` user has been deprecated in favor of the `kibana_system` user
The `kibana` user was historically used to authenticate {kib} to {es}.
The name of this user was confusing, and was often mistakenly used to login to {kib}.
This has been renamed to `kibana_system` in order to reduce confusion, and to better
align with other built-in system accounts.
If your `kibana.yml` used to contain:
[source,yaml]
--------------------------------------------------
elasticsearch.username: kibana
--------------------------------------------------
then you should update to use the new `kibana_system` user instead:
[source,yaml]
--------------------------------------------------
elasticsearch.username: kibana_system
--------------------------------------------------
[float]
[[builtin-roles-changes]]
==== Changes to built-in roles
[float]
===== The `kibana_user` role has been deprecated in favor of the `kibana_admin` role
Users who were previously assigned the `kibana_user` role should instead be assigned
the `kibana_admin` role. This role grants the same set of privileges as `kibana_user`, but has been
renamed to better reflect its intended use.
//end::notable-breaking-changes[]

View File

@ -10,7 +10,7 @@ are similar. For systems that are not ingesting the audit file for search or
analytics it is strongly recommended to keep only the newer format.
To turn off the deprecated output format, you can disable the logger in the
`log4j2.properties` file:
`log4j2.properties` file:
[source, properties]
--------------------------------------------------
@ -139,18 +139,18 @@ non-matching events are printed as usual.
All policies are defined under the `xpack.security.audit.logfile.events.ignore_filters`
settings namespace. For example, the following policy named _example1_ matches
events from the _kibana_ or _admin_user_ principals **and** operating over indices of the
events from the _kibana_system_ or _admin_user_ principals **and** operating over indices of the
wildcard form _app-logs*_:
[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
example1:
users: ["kibana", "admin_user"]
users: ["kibana_system", "admin_user"]
indices: ["app-logs*"]
----------------------------
An audit event generated by the _kibana_ user and operating over multiple indices
An audit event generated by the _kibana_system_ user and operating over multiple indices
, some of which do not match the indices wildcard, will not match.
As expected, operations generated by all other users (even operating only on indices that
match the _indices_ filter) will not match this policy either.

View File

@ -12,9 +12,9 @@ used to <<set-built-in-user-passwords,set all of the built-in user passwords>>.
`logstash_system`:: The user Logstash uses when storing monitoring information in {es}.
`beats_system`:: The user the Beats use when storing monitoring information in {es}.
`apm_system`:: The user the APM server uses when storing monitoring information in {es}.
`remote_monitoring_user`:: The user {metricbeat} uses when collecting and
storing monitoring information in {es}. It has the `remote_monitoring_agent` and
`remote_monitoring_collector` built-in roles.
`remote_monitoring_user`:: The user {metricbeat} uses when collecting and
storing monitoring information in {es}. It has the `remote_monitoring_agent` and
`remote_monitoring_collector` built-in roles.
TIP: The built-in users serve specific purposes and are not intended for general
use. In particular, do not use the `elastic` superuser unless full access to
@ -65,7 +65,7 @@ The +elasticsearch-setup-passwords+ tool is the simplest method to set the
built-in users' passwords for the first time. It uses the `elastic` user's
bootstrap password to run user management API requests. For example, you can run
the command in an "interactive" mode, which prompts you to enter new passwords
for the `elastic`, `kibana`, `logstash_system`, `beats_system`, `apm_system`,
for the `elastic`, `kibana_system`, `logstash_system`, `beats_system`, `apm_system`,
and `remote_monitoring_user` users:
[source,shell]
@ -107,7 +107,7 @@ since at that point the bootstrap password is no longer required.
[[add-built-in-user-kibana]]
==== Adding built-in user passwords to {kib}
After the `kibana` user password is set, you need to update the {kib} server
After the `kibana_system` user password is set, you need to update the {kib} server
with the new password by setting `elasticsearch.password` in the `kibana.yml`
configuration file:
@ -120,7 +120,7 @@ See {kibana-ref}/using-kibana-with-security.html[Configuring security in {kib}].
[float]
[[add-built-in-user-logstash]]
==== Adding built-in user passwords to {ls}
==== Adding built-in user passwords to {ls}
The `logstash_system` user is used internally within Logstash when
monitoring is enabled for Logstash.
@ -143,7 +143,7 @@ been changed, you can enable the user via the following API call:
PUT _security/user/logstash_system/_enable
---------------------------------------------------------------------
See {logstash-ref}/ls-security.html#ls-monitoring-user[Configuring credentials for {ls} monitoring].
See {logstash-ref}/ls-security.html#ls-monitoring-user[Configuring credentials for {ls} monitoring].
[float]
[[add-built-in-user-beats]]
@ -161,13 +161,13 @@ xpack.monitoring.elasticsearch.username: beats_system
xpack.monitoring.elasticsearch.password: beatspassword
----------------------------------------------------------
For example, see {metricbeat-ref}/monitoring.html[Monitoring {metricbeat}].
For example, see {metricbeat-ref}/monitoring.html[Monitoring {metricbeat}].
The `remote_monitoring_user` is used when {metricbeat} collects and stores
monitoring data for the {stack}. See <<monitoring-production>>.
The `remote_monitoring_user` is used when {metricbeat} collects and stores
monitoring data for the {stack}. See <<monitoring-production>>.
If you have upgraded from an older version of {es}, then you may not have set a
password for the `beats_system` or `remote_monitoring_user` users. If this is
password for the `beats_system` or `remote_monitoring_user` users. If this is
the case, then you should use the *Management > Users* page in {kib} or the
{ref}/security-api-change-password.html[Change Password API] to set a password
for these users.
@ -178,8 +178,8 @@ for these users.
The `apm_system` user is used internally within APM when monitoring is enabled.
To enable this feature in APM, you need to update the
{apm-server-ref-70}/configuring-howto-apm-server.html[APM configuration file] to
To enable this feature in APM, you need to update the
{apm-server-ref-70}/configuring-howto-apm-server.html[APM configuration file] to
reference the correct username and password. For example:
[source,yaml]
@ -188,10 +188,10 @@ xpack.monitoring.elasticsearch.username: apm_system
xpack.monitoring.elasticsearch.password: apmserverpassword
----------------------------------------------------------
See {apm-server-ref-70}/monitoring.html[Monitoring APM Server].
See {apm-server-ref-70}/monitoring.html[Monitoring APM Server].
If you have upgraded from an older version of {es}, then you may not have set a
password for the `apm_system` user. If this is the case,
password for the `apm_system` user. If this is the case,
then you should use the *Management > Users* page in {kib} or the
{ref}/security-api-change-password.html[Change Password API] to set a password
for these users.

View File

@ -1,13 +1,13 @@
// tag::create-users[]
There are <<built-in-users,built-in users>> that you can use for specific
administrative purposes: `apm_system`, `beats_system`, `elastic`, `kibana`,
`logstash_system`, and `remote_monitoring_user`.
administrative purposes: `apm_system`, `beats_system`, `elastic`, `kibana_system`,
`logstash_system`, and `remote_monitoring_user`.
// end::create-users[]
Before you can use them, you must set their passwords:
. Restart {es}. For example, if you installed {es} with a `.tar.gz` package, run
. Restart {es}. For example, if you installed {es} with a `.tar.gz` package, run
the following command from the {es} directory:
+
--

View File

@ -1,36 +1,36 @@
When the {es} {security-features} are enabled, users must log in to {kib}
with a valid user ID and password.
with a valid user ID and password.
{kib} also performs some tasks under the covers that require use of the
built-in `kibana` user.
{kib} also performs some tasks under the covers that require use of the
built-in `kibana_system` user.
. Configure {kib} to use the built-in `kibana` user and the password that you
. Configure {kib} to use the built-in `kibana_system` user and the password that you
created:
** If you don't mind having passwords visible in your configuration file,
uncomment and update the following settings in the `kibana.yml` file in your
** If you don't mind having passwords visible in your configuration file,
uncomment and update the following settings in the `kibana.yml` file in your
{kib} directory:
+
--
TIP: If you installed {kib} using archive distributions (`zip` or
`tar.gz`), the `kibana.yml` configuration file is in `KIBANA_HOME/config`. If
you used package distributions (Debian or RPM), it's in `/etc/kibana`. For more
information, see {kibana-ref}/settings.html[Configuring {kib}].
TIP: If you installed {kib} using archive distributions (`zip` or
`tar.gz`), the `kibana.yml` configuration file is in `KIBANA_HOME/config`. If
you used package distributions (Debian or RPM), it's in `/etc/kibana`. For more
information, see {kibana-ref}/settings.html[Configuring {kib}].
For example, add the following settings:
[source,yaml]
----
elasticsearch.username: "kibana"
elasticsearch.username: "kibana_system"
elasticsearch.password: "your_password"
----
Specify the password that you set with the `elasticsearch-setup-passwords`
command then save your changes to the file.
Specify the password that you set with the `elasticsearch-setup-passwords`
command then save your changes to the file.
--
** If you prefer not to put your user ID and password in the `kibana.yml` file,
store them in a keystore instead. Run the following commands to create the {kib}
** If you prefer not to put your user ID and password in the `kibana.yml` file,
store them in a keystore instead. Run the following commands to create the {kib}
keystore and add the secure settings:
+
--
@ -42,14 +42,14 @@ keystore and add the secure settings:
./bin/kibana-keystore add elasticsearch.password
----------------------------------------------------------------------
When prompted, specify the `kibana` built-in user and its password for these
setting values. The settings are automatically applied when you start {kib}.
When prompted, specify the `kibana_system` built-in user and its password for these
setting values. The settings are automatically applied when you start {kib}.
To learn more, see {kibana-ref}/secure-settings.html[Secure settings].
// end::store-kibana-user[]
--
. Restart {kib}. For example, if you installed
{kib} with a `.tar.gz` package, run the following command from the {kib}
. Restart {kib}. For example, if you installed
{kib} with a `.tar.gz` package, run the following command from the {kib}
directory:
+
--
@ -58,5 +58,5 @@ directory:
./bin/kibana
----------------------------------------------------------------------
See {kibana-ref}/start-stop.html[Starting and stopping {kib}].
--
See {kibana-ref}/start-stop.html[Starting and stopping {kib}].
--

View File

@ -1,7 +1,7 @@
[role="xpack"]
[testenv="trial"]
[[encrypting-internode]]
=== Encrypt internode communications
=== Encrypt internode communications
Now that we've generated a certificate authority and certificates, let's update
the cluster to use these files.
@ -9,7 +9,7 @@ the cluster to use these files.
IMPORTANT: When you enable {es} {security-features}, unless you have a trial
license, you must use Transport Layer Security (TLS) to encrypt internode
communication. By following the steps in this tutorial tutorial, you learn how
to meet the minimum requirements to pass the
to meet the minimum requirements to pass the
{ref}/bootstrap-checks-xpack.html#bootstrap-checks-tls[TLS bootstrap check].
. (Optional) Name the cluster.
@ -23,11 +23,11 @@ For example, add the {ref}/cluster.name.html[cluster.name] setting in the
cluster.name: test-cluster
----
TIP: The `ES_PATH_CONF` environment variable contains the path for the {es}
configuration files. If you installed {es} using archive distributions (`zip` or
`tar.gz`), it defaults to `ES_HOME/config`. If you used package distributions
(Debian or RPM), it defaults to `/etc/elasticsearch`. For more information, see
{ref}/settings.html[Configuring {es}].
TIP: The `ES_PATH_CONF` environment variable contains the path for the {es}
configuration files. If you installed {es} using archive distributions (`zip` or
`tar.gz`), it defaults to `ES_HOME/config`. If you used package distributions
(Debian or RPM), it defaults to `/etc/elasticsearch`. For more information, see
<<settings>>.
The default cluster name is `elasticsearch`. You should choose a unique name,
however, to ensure that your nodes join the right cluster.
@ -46,7 +46,7 @@ node.name: node-1
In this tutorial, the cluster will consist of three nodes that exist on the same
machine and share the same (loopback) IP address and hostname. Therefore, we
must give each node a unique name.
must give each node a unique name.
This step is also necessary if you want to use the `node.name` value to define
the location of certificates in subsequent steps.
@ -79,13 +79,13 @@ itself into a new cluster.
TIP: If you are starting a cluster with multiple master-eligible nodes for the
first time, add all of those node names to the `cluster.initial_master_nodes`
setting.
See {ref}/modules-discovery-bootstrap-cluster.html[Bootstrapping a cluster] and
{ref}/discovery-settings.html[Important discovery and cluster formation settings].
--
. Enable Transport Layer Security (TLS/SSL) for transport (internode)
communications.
communications.
+
--
// tag::enable-tls[]
@ -95,20 +95,20 @@ file:
[source,yaml]
----
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: certs/${node.name}.p12 <1>
xpack.security.transport.ssl.truststore.path: certs/${node.name}.p12
----
<1> If the file name for your certificate does not match the `node.name` value,
you must put the appropriate file name in the `elasticsearch.yml` file.
you must put the appropriate file name in the `elasticsearch.yml` file.
// end::enable-tls[]
NOTE: The PKCS#12 keystore that is output by the `elasticsearch-certutil` can be
used as both a keystore and a truststore. If you use other tools to manage and
used as both a keystore and a truststore. If you use other tools to manage and
generate your certificates, you might have different values for these settings,
but that scenario is not covered in this tutorial.
For more information, see <<get-started-enable-security>> and
For more information, see <<get-started-enable-security>> and
{ref}/security-settings.html#transport-tls-ssl-settings[Transport TLS settings].
--
@ -116,7 +116,7 @@ For more information, see <<get-started-enable-security>> and
+
--
// tag::secure-passwords[]
For example, run the following commands:
For example, run the following commands:
["source","sh",subs="attributes,callouts"]
----------------------------------------------------------------------
@ -146,7 +146,7 @@ command from the {es} directory:
----------------------------------------------------------------------
--
. Create passwords for the built-in users and configure {kib} to use them.
. Create passwords for the built-in users and configure {kib} to use them.
+
--
NOTE: If you already configured passwords for these users in other tutorials,
@ -154,11 +154,11 @@ you can skip this step.
include::{xes-repo-dir}/security/get-started-builtin-users.asciidoc[tag=create-users]
After you setup the password for the `kibana` built-in user,
After you setup the password for the `kibana_system` built-in user,
<<get-started-kibana-user,configure {kib} to use it>>.
For example, run the following commands to create the {kib} keystore and add the
`kibana` built-in user and its password in secure settings:
`kibana_system` built-in user and its password in secure settings:
include::{xes-repo-dir}/security/get-started-kibana-users.asciidoc[tag=store-kibana-user]
--
@ -173,5 +173,5 @@ command from the {kib} directory:
./bin/kibana
----------------------------------------------------------------------
See {kibana-ref}/start-stop.html[Starting and stopping {kib}].
See {kibana-ref}/start-stop.html[Starting and stopping {kib}].
--

View File

@ -16,6 +16,7 @@ public class ClientReservedRealm {
assert username != null;
switch (username) {
case UsernamesField.ELASTIC_NAME:
case UsernamesField.DEPRECATED_KIBANA_NAME:
case UsernamesField.KIBANA_NAME:
case UsernamesField.LOGSTASH_NAME:
case UsernamesField.BEATS_NAME:

View File

@ -0,0 +1,21 @@
/*
* 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.core.security.user;
import org.elasticsearch.xpack.core.security.support.MetadataUtils;
/**
* Built in user for the kibana server
*/
public class KibanaSystemUser extends User {
public static final String NAME = UsernamesField.KIBANA_NAME;
public static final String ROLE_NAME = UsernamesField.KIBANA_ROLE;
public KibanaSystemUser(boolean enabled) {
super(NAME, new String[]{ ROLE_NAME }, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, enabled);
}
}

View File

@ -9,13 +9,16 @@ import org.elasticsearch.xpack.core.security.support.MetadataUtils;
/**
* Built in user for the kibana server
* @deprecated use KibanaSystemUser
*/
@Deprecated
public class KibanaUser extends User {
public static final String NAME = UsernamesField.KIBANA_NAME;
public static final String NAME = UsernamesField.DEPRECATED_KIBANA_NAME;
public static final String ROLE_NAME = UsernamesField.KIBANA_ROLE;
public KibanaUser(boolean enabled) {
super(NAME, new String[]{ ROLE_NAME }, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, enabled);
super(NAME, new String[]{ ROLE_NAME }, null, null,
MetadataUtils.getDeprecatedReservedMetadata("Please use the [kibana_system] user instead."), enabled);
}
}

View File

@ -8,7 +8,8 @@ package org.elasticsearch.xpack.core.security.user;
public final class UsernamesField {
public static final String ELASTIC_NAME = "elastic";
public static final String ELASTIC_ROLE = "superuser";
public static final String KIBANA_NAME = "kibana";
public static final String DEPRECATED_KIBANA_NAME = "kibana";
public static final String KIBANA_NAME = "kibana_system";
public static final String KIBANA_ROLE = "kibana_system";
public static final String SYSTEM_NAME = "_system";
public static final String SYSTEM_ROLE = "_system";

View File

@ -46,7 +46,7 @@ public class IdentityProviderAuthenticationIT extends IdpRestTestCase {
@Before
public void setupSecurityData() throws IOException {
setUserPassword("kibana", new SecureString("kibana".toCharArray()));
setUserPassword("kibana_system", new SecureString("kibana_system".toCharArray()));
createApplicationPrivileges("elastic-cloud", org.elasticsearch.common.collect.Map.of(
"deployment_admin", Set.of("sso:admin"),
"deployment_viewer", Set.of("sso:viewer"))
@ -114,7 +114,7 @@ public class IdentityProviderAuthenticationIT extends IdpRestTestCase {
private SamlPrepareAuthenticationResponse generateSamlAuthnRequest(String realmName) throws Exception {
final Request request = new Request("POST", "/_security/saml/prepare");
request.setJsonEntity("{\"realm\":\"" + realmName + "\"}");
try (RestClient kibanaClient = restClientAsKibana()) {
try (RestClient kibanaClient = restClientAsKibanaSystem()) {
final Response response = kibanaClient.performRequest(request);
final Map<String, Object> map = entityAsMap(response);
assertThat(ObjectPath.eval("realm", map), equalTo(realmName));
@ -153,7 +153,7 @@ public class IdentityProviderAuthenticationIT extends IdpRestTestCase {
request.setJsonEntity("{\"content\":\"" + encodedResponse + "\", \"realm\":\"" + REALM_NAME + "\"}");
}
final String accessToken;
try (RestClient kibanaClient = restClientAsKibana()) {
try (RestClient kibanaClient = restClientAsKibanaSystem()) {
final Response response = kibanaClient.performRequest(request);
final Map<String, Object> map = entityAsMap(response);
assertThat(ObjectPath.eval("username", map), instanceOf(String.class));
@ -185,10 +185,10 @@ public class IdentityProviderAuthenticationIT extends IdpRestTestCase {
getClusterHosts().toArray(new HttpHost[getClusterHosts().size()]));
}
private RestClient restClientAsKibana() throws IOException {
private RestClient restClientAsKibanaSystem() throws IOException {
return buildClient(
Settings.builder().put(ThreadContext.PREFIX + ".Authorization", basicAuthHeaderValue("kibana",
new SecureString("kibana".toCharArray()))).build(),
Settings.builder().put(ThreadContext.PREFIX + ".Authorization", basicAuthHeaderValue("kibana_system",
new SecureString("kibana_system".toCharArray()))).build(),
getClusterHosts().toArray(new HttpHost[getClusterHosts().size()]));
}
}

View File

@ -9,6 +9,7 @@ import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.util.Supplier;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.settings.KeyStoreWrapper;
import org.elasticsearch.common.settings.SecureSetting;
import org.elasticsearch.common.settings.SecureString;
@ -24,10 +25,12 @@ import org.elasticsearch.xpack.core.security.authc.esnative.ClientReservedRealm;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.xpack.core.security.support.Exceptions;
import org.elasticsearch.xpack.core.security.support.MetadataUtils;
import org.elasticsearch.xpack.core.security.user.APMSystemUser;
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
import org.elasticsearch.xpack.core.security.user.BeatsSystemUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.RemoteMonitoringUser;
@ -41,6 +44,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* A realm for predefined users. These users can only be modified in terms of changing their passwords; no other modifications are allowed.
@ -66,6 +70,8 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
private final ReservedUserInfo disabledDefaultUserInfo;
private final ReservedUserInfo enabledDefaultUserInfo;
private final DeprecationLogger deprecationLogger = new DeprecationLogger(logger);
public ReservedRealm(Environment env, Settings settings, NativeUsersStore nativeUsersStore, AnonymousUser anonymousUser,
SecurityIndexManager securityIndex, ThreadPool threadPool) {
super(new RealmConfig(new RealmConfig.RealmIdentifier(TYPE, TYPE), settings, env, threadPool.getThreadContext()), threadPool);
@ -98,6 +104,7 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
result = AuthenticationResult.terminate("failed to authenticate user [" + token.principal() + "]", null);
} else if (userInfo.verifyPassword(token.credentials())) {
final User user = getUser(token.principal(), userInfo);
logDeprecatedUser(user);
result = AuthenticationResult.success(user);
} else {
result = AuthenticationResult.terminate("failed to authenticate user [" + token.principal() + "]", null);
@ -147,6 +154,8 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
return new ElasticUser(userInfo.enabled);
case KibanaUser.NAME:
return new KibanaUser(userInfo.enabled);
case KibanaSystemUser.NAME:
return new KibanaSystemUser(userInfo.enabled);
case LogstashSystemUser.NAME:
return new LogstashSystemUser(userInfo.enabled);
case BeatsSystemUser.NAME:
@ -177,6 +186,9 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
userInfo = reservedUserInfos.get(KibanaUser.NAME);
users.add(new KibanaUser(userInfo == null || userInfo.enabled));
userInfo = reservedUserInfos.get(KibanaSystemUser.NAME);
users.add(new KibanaSystemUser(userInfo == null || userInfo.enabled));
userInfo = reservedUserInfos.get(LogstashSystemUser.NAME);
users.add(new LogstashSystemUser(userInfo == null || userInfo.enabled));
@ -223,6 +235,15 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
}
}
private void logDeprecatedUser(final User user){
Map<String, Object> metadata = user.metadata();
if (Boolean.TRUE.equals(metadata.get(MetadataUtils.DEPRECATED_METADATA_KEY))) {
deprecationLogger.deprecatedAndMaybeLog("deprecated_user-" + user.principal(), "The user [" + user.principal() +
"] is deprecated and will be removed in a future version of Elasticsearch. " +
metadata.get(MetadataUtils.DEPRECATED_REASON_METADATA_KEY));
}
}
private ReservedUserInfo getDefaultUserInfo(String username) {
if (ElasticUser.NAME.equals(username)) {
return bootstrapUserInfo.deepClone();

View File

@ -30,6 +30,7 @@ import org.elasticsearch.xpack.core.security.support.Validation;
import org.elasticsearch.xpack.core.security.user.APMSystemUser;
import org.elasticsearch.xpack.core.security.user.BeatsSystemUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.RemoteMonitoringUser;
@ -46,7 +47,9 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -65,8 +68,14 @@ import static java.util.Arrays.asList;
public class SetupPasswordTool extends LoggingAwareMultiCommand {
private static final char[] CHARS = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789").toCharArray();
public static final List<String> USERS = asList(ElasticUser.NAME, APMSystemUser.NAME, KibanaUser.NAME, LogstashSystemUser.NAME,
BeatsSystemUser.NAME, RemoteMonitoringUser.NAME);
public static final List<String> USERS = asList(ElasticUser.NAME, APMSystemUser.NAME, KibanaUser.NAME, KibanaSystemUser.NAME,
LogstashSystemUser.NAME, BeatsSystemUser.NAME, RemoteMonitoringUser.NAME);
public static final Map<String, String> USERS_WITH_SHARED_PASSWORDS = Collections.unmodifiableMap(new HashMap<String, String>() {
{
put(KibanaSystemUser.NAME, KibanaUser.NAME);
}
});
private final BiFunction<Environment, Settings, CommandLineHttpClient> clientFunction;
private final CheckedFunction<Environment, KeyStoreWrapper, Exception> keyStoreFunction;
@ -503,10 +512,18 @@ public class SetupPasswordTool extends LoggingAwareMultiCommand {
*/
void changePasswords(CheckedFunction<String, SecureString, UserException> passwordFn,
CheckedBiConsumer<String, SecureString, Exception> successCallback, Terminal terminal) throws Exception {
Map<String, SecureString> passwordsMap = new HashMap<>(USERS.size());
Map<String, SecureString> passwordsMap = new LinkedHashMap<>(USERS.size());
try {
for (String user : USERS) {
passwordsMap.put(user, passwordFn.apply(user));
if (USERS_WITH_SHARED_PASSWORDS.containsValue(user)) {
continue;
}
SecureString password = passwordFn.apply(user);
passwordsMap.put(user, password);
if (USERS_WITH_SHARED_PASSWORDS.containsKey(user)) {
passwordsMap.put(USERS_WITH_SHARED_PASSWORDS.get(user), password.clone());
}
}
/*
* Change elastic user last. This tool will not run after the elastic user

View File

@ -27,13 +27,13 @@ public class KibanaSystemRoleIntegTests extends SecurityIntegTestCase {
public String configUsers() {
final String usersPasswdHashed = new String(getFastStoredHashAlgoForTests().hash(USERS_PASSWD));
return super.configUsers() +
"kibana_system:" + usersPasswdHashed;
"my_kibana_system:" + usersPasswdHashed;
}
@Override
public String configUsersRoles() {
return super.configUsersRoles() +
"kibana_system:kibana_system";
"kibana_system:my_kibana_system";
}
@ -42,13 +42,14 @@ public class KibanaSystemRoleIntegTests extends SecurityIntegTestCase {
if (randomBoolean()) {
CreateIndexResponse createIndexResponse = client().filterWithHeader(singletonMap("Authorization",
UsernamePasswordToken.basicAuthHeaderValue("kibana_system", USERS_PASSWD)))
UsernamePasswordToken.basicAuthHeaderValue("my_kibana_system", USERS_PASSWD)))
.admin().indices().prepareCreate(index).get();
assertThat(createIndexResponse.isAcknowledged(), is(true));
}
IndexResponse response = client()
.filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_system", USERS_PASSWD)))
.filterWithHeader(singletonMap("Authorization",
UsernamePasswordToken.basicAuthHeaderValue("my_kibana_system", USERS_PASSWD)))
.prepareIndex()
.setIndex(index)
.setType("dashboard")
@ -58,7 +59,8 @@ public class KibanaSystemRoleIntegTests extends SecurityIntegTestCase {
assertEquals(DocWriteResponse.Result.CREATED, response.getResult());
DeleteResponse deleteResponse = client()
.filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_system", USERS_PASSWD)))
.filterWithHeader(singletonMap("Authorization",
UsernamePasswordToken.basicAuthHeaderValue("my_kibana_system", USERS_PASSWD)))
.prepareDelete(index, "dashboard", response.getId())
.get();
assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult());

View File

@ -17,6 +17,7 @@ import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.core.security.user.APMSystemUser;
import org.elasticsearch.xpack.core.security.user.BeatsSystemUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.RemoteMonitoringUser;
@ -103,8 +104,8 @@ public abstract class NativeRealmIntegTestCase extends SecurityIntegTestCase {
RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
optionsBuilder.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(ElasticUser.NAME, reservedPassword));
RequestOptions options = optionsBuilder.build();
final List<String> usernames = Arrays.asList(KibanaUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME,
RemoteMonitoringUser.NAME);
final List<String> usernames = Arrays.asList(KibanaUser.NAME, KibanaSystemUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME,
APMSystemUser.NAME, RemoteMonitoringUser.NAME);
for (String username : usernames) {
Request request = new Request("PUT", "/_security/user/" + username + "/_password");
request.setJsonEntity("{\"password\": \"" + new String(reservedPassword.getChars()) + "\"}");

View File

@ -31,6 +31,7 @@ import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
import org.elasticsearch.xpack.core.security.user.APMSystemUser;
import org.elasticsearch.xpack.core.security.user.BeatsSystemUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.RemoteMonitoringUser;
@ -86,8 +87,8 @@ public class NativeUsersStoreTests extends ESTestCase {
public void testPasswordUpsertWhenSetEnabledOnReservedUser() throws Exception {
final NativeUsersStore nativeUsersStore = startNativeUsersStore();
final String user = randomFrom(ElasticUser.NAME, KibanaUser.NAME, LogstashSystemUser.NAME,
BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final String user = randomFrom(ElasticUser.NAME, KibanaUser.NAME, KibanaSystemUser.NAME,
LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final PlainActionFuture<Void> future = new PlainActionFuture<>();
nativeUsersStore.setEnabled(user, true, WriteRequest.RefreshPolicy.IMMEDIATE, future);
@ -105,8 +106,8 @@ public class NativeUsersStoreTests extends ESTestCase {
public void testBlankPasswordInIndexImpliesDefaultPassword() throws Exception {
final NativeUsersStore nativeUsersStore = startNativeUsersStore();
final String user = randomFrom(ElasticUser.NAME, KibanaUser.NAME, LogstashSystemUser.NAME,
BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final String user = randomFrom(ElasticUser.NAME, KibanaUser.NAME, KibanaSystemUser.NAME,
LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final Map<String, Object> values = new HashMap<>();
values.put(ENABLED_FIELD, Boolean.TRUE);
values.put(PASSWORD_FIELD, BLANK_PASSWORD);

View File

@ -16,6 +16,7 @@ import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.core.security.user.APMSystemUser;
import org.elasticsearch.xpack.core.security.user.BeatsSystemUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.RemoteMonitoringUser;
@ -52,8 +53,8 @@ public class ReservedRealmIntegTests extends NativeRealmIntegTestCase {
}
public void testAuthenticate() {
final List<String> usernames = Arrays.asList(ElasticUser.NAME, KibanaUser.NAME, LogstashSystemUser.NAME,
BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final List<String> usernames = Arrays.asList(ElasticUser.NAME, KibanaUser.NAME, KibanaSystemUser.NAME,
LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
for (String username : usernames) {
ClusterHealthResponse response = client()
.filterWithHeader(singletonMap("Authorization", basicAuthHeaderValue(username, getReservedPassword())))
@ -72,8 +73,8 @@ public class ReservedRealmIntegTests extends NativeRealmIntegTestCase {
*/
public void testAuthenticateAfterEnablingUser() {
final SecurityClient c = securityClient();
final List<String> usernames = Arrays.asList(ElasticUser.NAME, KibanaUser.NAME, LogstashSystemUser.NAME,
BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final List<String> usernames = Arrays.asList(ElasticUser.NAME, KibanaUser.NAME, KibanaSystemUser.NAME,
LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
for (String username : usernames) {
c.prepareSetEnabled(username, true).get();
ClusterHealthResponse response = client()
@ -88,8 +89,8 @@ public class ReservedRealmIntegTests extends NativeRealmIntegTestCase {
}
public void testChangingPassword() {
String username = randomFrom(ElasticUser.NAME, KibanaUser.NAME, LogstashSystemUser.NAME,
BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
String username = randomFrom(ElasticUser.NAME, KibanaUser.NAME, KibanaSystemUser.NAME,
LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME, RemoteMonitoringUser.NAME);
final char[] newPassword = "supersecretvalue".toCharArray();
if (randomBoolean()) {

View File

@ -25,6 +25,7 @@ import org.elasticsearch.xpack.core.security.user.APMSystemUser;
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
import org.elasticsearch.xpack.core.security.user.BeatsSystemUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.RemoteMonitoringUser;
@ -169,6 +170,11 @@ public class ReservedRealmTests extends ESTestCase {
verify(securityIndex, times(2)).checkMappingVersion(predicateCaptor.capture());
verifyVersionPredicate(principal, predicateCaptor.getValue());
verifyNoMoreInteractions(usersStore);
if (new KibanaUser(enabled).equals(expectedUser)) {
assertWarnings("The user [kibana] is deprecated and will be removed in a future version of Elasticsearch. " +
"Please use the [kibana_system] user instead.");
}
}
public void testLookup() throws Exception {
@ -264,8 +270,8 @@ public class ReservedRealmTests extends ESTestCase {
PlainActionFuture<Collection<User>> userFuture = new PlainActionFuture<>();
reservedRealm.users(userFuture);
assertThat(userFuture.actionGet(),
containsInAnyOrder(new ElasticUser(true), new KibanaUser(true), new LogstashSystemUser(true),
new BeatsSystemUser(true), new APMSystemUser(true), new RemoteMonitoringUser(true)));
containsInAnyOrder(new ElasticUser(true), new KibanaUser(true), new KibanaSystemUser(true),
new LogstashSystemUser(true), new BeatsSystemUser(true), new APMSystemUser(true), new RemoteMonitoringUser(true)));
}
public void testGetUsersDisabled() {
@ -397,8 +403,8 @@ public class ReservedRealmTests extends ESTestCase {
new AnonymousUser(Settings.EMPTY), securityIndex, threadPool);
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
final String principal = randomFrom(KibanaUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME,
RemoteMonitoringUser.NAME);
final String principal = randomFrom(KibanaUser.NAME, KibanaSystemUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME,
APMSystemUser.NAME, RemoteMonitoringUser.NAME);
doAnswer((i) -> {
ActionListener callback = (ActionListener) i.getArguments()[1];
callback.onResponse(null);
@ -420,16 +426,16 @@ public class ReservedRealmTests extends ESTestCase {
new AnonymousUser(Settings.EMPTY), securityIndex, threadPool);
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
final String principal = randomFrom(KibanaUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME, APMSystemUser.NAME,
RemoteMonitoringUser.NAME);
final String principal = randomFrom(KibanaUser.NAME, KibanaSystemUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME,
APMSystemUser.NAME, RemoteMonitoringUser.NAME);
reservedRealm.doAuthenticate(new UsernamePasswordToken(principal, mockSecureSettings.getString("bootstrap.password")), listener);
final AuthenticationResult result = listener.get();
assertThat(result.getStatus(), is(AuthenticationResult.Status.TERMINATE));
}
private User randomReservedUser(boolean enabled) {
return randomFrom(new ElasticUser(enabled), new KibanaUser(enabled), new LogstashSystemUser(enabled),
new BeatsSystemUser(enabled), new APMSystemUser(enabled), new RemoteMonitoringUser(enabled));
return randomFrom(new ElasticUser(enabled), new KibanaUser(enabled), new KibanaSystemUser(enabled),
new LogstashSystemUser(enabled), new BeatsSystemUser(enabled), new APMSystemUser(enabled), new RemoteMonitoringUser(enabled));
}
/*

View File

@ -111,6 +111,18 @@ public class SetupPasswordToolTests extends CommandTestCase {
// elastic user is updated last
usersInSetOrder = new ArrayList<>(SetupPasswordTool.USERS);
usersInSetOrder.sort((user1, user2) -> {
if (SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsKey(user1)
&& SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsValue(user2)) {
return -1;
}
if (SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsKey(user2)
&& SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsValue(user1)) {
return 1;
}
return 0;
});
for (int i = 0; i < usersInSetOrder.size() - 1; i++) {
if (ElasticUser.NAME.equals(usersInSetOrder.get(i))) {
Collections.swap(usersInSetOrder, i, i + 1);
@ -118,6 +130,9 @@ public class SetupPasswordToolTests extends CommandTestCase {
}
for (String user : SetupPasswordTool.USERS) {
if (SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsValue(user)) {
continue;
}
terminal.addSecretInput(user + "-password");
terminal.addSecretInput(user + "-password");
}
@ -168,11 +183,26 @@ public class SetupPasswordToolTests extends CommandTestCase {
URL checkUrl = authenticateUrl(url);
inOrder.verify(httpClient).execute(eq("GET"), eq(checkUrl), eq(ElasticUser.NAME), eq(bootstrapPassword), any(CheckedSupplier.class),
any(CheckedFunction.class));
Map<String, String> capturedPasswords = new HashMap<>(usersInSetOrder.size());
for (String user : usersInSetOrder) {
URL urlWithRoute = passwordUrl(url, user);
ArgumentCaptor<CheckedSupplier<String, Exception>> passwordCaptor = ArgumentCaptor.forClass((Class) CheckedSupplier.class);
inOrder.verify(httpClient).execute(eq("PUT"), eq(urlWithRoute), eq(ElasticUser.NAME), eq(bootstrapPassword),
any(CheckedSupplier.class), any(CheckedFunction.class));
passwordCaptor.capture(), any(CheckedFunction.class));
String userPassword = passwordCaptor.getValue().get();
capturedPasswords.put(user, userPassword);
}
for (Map.Entry<String, String> entry : SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.entrySet()) {
assertEquals(capturedPasswords.get(entry.getKey()), capturedPasswords.get(entry.getValue()));
capturedPasswords.remove(entry.getKey());
capturedPasswords.remove(entry.getValue());
}
Set<String> uniqueCapturedPasswords = new HashSet<>(capturedPasswords.values());
assertEquals(uniqueCapturedPasswords.size(), capturedPasswords.size());
}
public void testAuthnFail() throws Exception {
@ -391,12 +421,13 @@ public class SetupPasswordToolTests extends CommandTestCase {
URL checkUrl = authenticateUrl(url);
inOrder.verify(httpClient).execute(eq("GET"), eq(checkUrl), eq(ElasticUser.NAME), eq(bootstrapPassword), any(CheckedSupplier.class),
any(CheckedFunction.class));
for (String user : usersInSetOrder) {
URL urlWithRoute = passwordUrl(url, user);
ArgumentCaptor<CheckedSupplier<String, Exception>> passwordCaptor = ArgumentCaptor.forClass((Class) CheckedSupplier.class);
inOrder.verify(httpClient).execute(eq("PUT"), eq(urlWithRoute), eq(ElasticUser.NAME), eq(bootstrapPassword),
passwordCaptor.capture(), any(CheckedFunction.class));
assertThat(passwordCaptor.getValue().get(), containsString(user + "-password"));
assertThat(passwordCaptor.getValue().get(), containsString(getExpectedPasswordForUser(user)));
}
}
@ -409,6 +440,10 @@ public class SetupPasswordToolTests extends CommandTestCase {
}
terminal.addTextInput("Y");
for (String user : SetupPasswordTool.USERS) {
if (SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsValue(user)) {
continue;
}
// fail in strength and match
int failCount = randomIntBetween(3, 10);
while (failCount-- > 0) {
@ -437,7 +472,7 @@ public class SetupPasswordToolTests extends CommandTestCase {
ArgumentCaptor<CheckedSupplier<String, Exception>> passwordCaptor = ArgumentCaptor.forClass((Class) CheckedSupplier.class);
inOrder.verify(httpClient).execute(eq("PUT"), eq(urlWithRoute), eq(ElasticUser.NAME), eq(bootstrapPassword),
passwordCaptor.capture(), any(CheckedFunction.class));
assertThat(passwordCaptor.getValue().get(), containsString(user + "-password"));
assertThat(passwordCaptor.getValue().get(), containsString(getExpectedPasswordForUser(user)));
}
}
@ -510,4 +545,16 @@ public class SetupPasswordToolTests extends CommandTestCase {
};
}
private String getExpectedPasswordForUser(String user) throws Exception {
if (SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.containsValue(user)) {
for(Map.Entry<String, String> entry : SetupPasswordTool.USERS_WITH_SHARED_PASSWORDS.entrySet()) {
if (entry.getValue().equals(user)) {
return entry.getKey() + "-password";
}
}
throw new Exception("Expected to find corresponding user for " + user);
}
return user + "-password";
}
}

View File

@ -83,7 +83,7 @@ public class PkiAuthDelegationIntegTests extends SecurityIntegTestCase {
"user_manage_security:" + usersPasswdHashed + "\n" +
"user_delegate_pki:" + usersPasswdHashed + "\n" +
"user_all:" + usersPasswdHashed + "\n" +
"kibana_system:" + usersPasswdHashed + "\n";
"my_kibana_system:" + usersPasswdHashed + "\n";
}
@Override
@ -109,7 +109,7 @@ public class PkiAuthDelegationIntegTests extends SecurityIntegTestCase {
"role_manage_security:user_manage_security\n" +
"role_delegate_pki:user_delegate_pki\n" +
"role_all:user_all\n" +
"kibana_system:kibana_system\n";
"kibana_system:my_kibana_system\n";
}
@Override
@ -140,7 +140,7 @@ public class PkiAuthDelegationIntegTests extends SecurityIntegTestCase {
}
try (RestHighLevelClient restClient = new TestRestHighLevelClient()) {
for (String delegateeUsername : Arrays.asList("user_all", "user_delegate_pki", "kibana_system")) {
for (String delegateeUsername : Arrays.asList("user_all", "user_delegate_pki", "my_kibana_system")) {
// delegate
RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
optionsBuilder.addHeader("Authorization",
@ -177,7 +177,7 @@ public class PkiAuthDelegationIntegTests extends SecurityIntegTestCase {
}
try (RestHighLevelClient restClient = new TestRestHighLevelClient()) {
String delegateeUsername = randomFrom("user_all", "user_delegate_pki", "kibana_system");
String delegateeUsername = randomFrom("user_all", "user_delegate_pki", "my_kibana_system");
// delegate
RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
optionsBuilder.addHeader("Authorization",

View File

@ -10,6 +10,7 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.security.user.AsyncSearchUser;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.InternalUserSerializationHelper;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.SystemUser;
import org.elasticsearch.xpack.core.security.user.User;
@ -124,5 +125,12 @@ public class UserSerializationTests extends ESTestCase {
readFrom = User.readFrom(output.bytes().streamInput());
assertEquals(kibanaUser, readFrom);
final KibanaSystemUser kibanaSystemUser = new KibanaSystemUser(true);
output = new BytesStreamOutput();
User.writeTo(kibanaSystemUser, output);
readFrom = User.readFrom(output.bytes().streamInput());
assertEquals(kibanaSystemUser, readFrom);
}
}

View File

@ -9,6 +9,7 @@ import org.elasticsearch.cli.MockTerminal;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.WarningsHandler;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.io.PathUtils;
@ -98,7 +99,7 @@ public class SetupPasswordToolIT extends ESRestTestCase {
}
});
assertEquals(6, userPasswordMap.size());
assertEquals(7, userPasswordMap.size());
userPasswordMap.entrySet().forEach(entry -> {
final String basicHeader = "Basic " +
Base64.getEncoder().encodeToString((entry.getKey() + ":" + entry.getValue()).getBytes(StandardCharsets.UTF_8));
@ -106,6 +107,10 @@ public class SetupPasswordToolIT extends ESRestTestCase {
Request request = new Request("GET", "/_security/_authenticate");
RequestOptions.Builder options = request.getOptions().toBuilder();
options.addHeader("Authorization", basicHeader);
if ("kibana".equals(entry.getKey())) {
// the kibana user is deprecated so a warning header is expected
options.setWarningsHandler(WarningsHandler.PERMISSIVE);
}
request.setOptions(options);
Map<String, Object> userInfoMap = entityAsMap(client().performRequest(request));
assertEquals(entry.getKey(), userInfoMap.get("username"));