From 25d21570d6c9074409c80a5251a16cf3bd2a2130 Mon Sep 17 00:00:00 2001 From: uboness Date: Mon, 27 Oct 2014 16:10:28 +0100 Subject: [PATCH] Better shield user configuration Added `shield.user` setting so that the clients won't need to go through the unnatural and tedious process of configuring the `Authorization` header directly (that also requires the user to applicat the base64(username:password) logic. Now, the user can just set the following settings to bind a user to the client: ```yaml shield.user: 'username:password' ``` Original commit: elastic/x-pack-elasticsearch@94be3abd92d0320ad34c259c588adad5748dedb2 --- .../shield/plugin/ShieldPlugin.java | 32 +++++++++++++++++++ .../shield/test/ShieldIntegrationTest.java | 20 +++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/elasticsearch/shield/plugin/ShieldPlugin.java b/src/main/java/org/elasticsearch/shield/plugin/ShieldPlugin.java index a57f4ed8fe8..93019e01cd0 100644 --- a/src/main/java/org/elasticsearch/shield/plugin/ShieldPlugin.java +++ b/src/main/java/org/elasticsearch/shield/plugin/ShieldPlugin.java @@ -5,11 +5,17 @@ */ package org.elasticsearch.shield.plugin; +import org.elasticsearch.client.support.Headers; import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.inject.Module; +import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.shield.ShieldModule; +import org.elasticsearch.shield.ShieldSettingsException; +import org.elasticsearch.shield.authc.support.SecuredString; +import org.elasticsearch.shield.authc.support.UsernamePasswordToken; import java.io.File; import java.nio.file.Path; @@ -22,6 +28,12 @@ public class ShieldPlugin extends AbstractPlugin { public static final String NAME = "shield"; + private final Settings settings; + + public ShieldPlugin(Settings settings) { + this.settings = settings; + } + @Override public String name() { return NAME; @@ -37,6 +49,26 @@ public class ShieldPlugin extends AbstractPlugin { return ImmutableList.>of(ShieldModule.class); } + @Override + public Settings additionalSettings() { + String setting = Headers.PREFIX + "." + UsernamePasswordToken.BASIC_AUTH_HEADER; + if (settings.get(setting) != null) { + return ImmutableSettings.EMPTY; + } + String user = settings.get("shield.user"); + if (user == null) { + return ImmutableSettings.EMPTY; + } + int i = user.indexOf(":"); + if (i < 0 || i == user.length() - 1) { + throw new ShieldSettingsException("Invalid [shield.user] settings. Must be in the form of \":\""); + } + String username = user.substring(0, i); + String password = user.substring(i + 1); + return ImmutableSettings.builder() + .put(setting, UsernamePasswordToken.basicAuthHeaderValue(username, new SecuredString(password.toCharArray()))).build(); + } + public static Path configDir(Environment env) { return new File(env.configFile(), NAME).toPath(); } diff --git a/src/test/java/org/elasticsearch/shield/test/ShieldIntegrationTest.java b/src/test/java/org/elasticsearch/shield/test/ShieldIntegrationTest.java index 101f1afd9b1..e037b4790cd 100644 --- a/src/test/java/org/elasticsearch/shield/test/ShieldIntegrationTest.java +++ b/src/test/java/org/elasticsearch/shield/test/ShieldIntegrationTest.java @@ -63,7 +63,6 @@ public abstract class ShieldIntegrationTest extends ElasticsearchIntegrationTest File folder = newFolder(); ImmutableSettings.Builder builder = ImmutableSettings.builder() - .put("request.headers.Authorization", basicAuthHeaderValue(getClientUsername(), getClientPassword())) .put("discovery.zen.ping.multicast.enabled", false) .put("discovery.type", "zen") .put("node.mode", "network") @@ -76,6 +75,8 @@ public abstract class ShieldIntegrationTest extends ElasticsearchIntegrationTest .put("shield.audit.enabled", true) .put("plugins.load_classpath_plugins", false); + setUser(builder); + if (OsUtils.MAC) { builder.put("network.host", randomBoolean() ? "127.0.0.1" : "::1"); } @@ -97,13 +98,24 @@ public abstract class ShieldIntegrationTest extends ElasticsearchIntegrationTest @Override protected Settings transportClientSettings() { - return ImmutableSettings.builder() + ImmutableSettings.Builder builder = ImmutableSettings.builder() .put("request.headers.Authorization", basicAuthHeaderValue(getClientUsername(), getClientPassword())) .put(TransportModule.TRANSPORT_TYPE_KEY, NettySecuredTransport.class.getName()) .put("plugins." + PluginsService.LOAD_PLUGIN_FROM_CLASSPATH, false) .put("node.mode", "network") - .put(getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks", "testclient")) - .build(); + .put(getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks", "testclient")); + + setUser(builder); + + return builder.build(); + } + + protected void setUser(ImmutableSettings.Builder settings) { + if (randomBoolean()) { + settings.put("request.headers.Authorization", basicAuthHeaderValue(getClientUsername(), getClientPassword())); + } else { + settings.put("shield.user", getClientUsername() + ":" + new String(getClientPassword().internalChars())); + } } protected String writeFile(File folder, String name, String content) {