do not copy the authorization header from rest requests

Currently we copy the authorization header from every rest request to the action request. This is not
necessary because the user associated with each request is copied into the context and then if the
request leaves the node, the user will be serialized into a string and attached as a header.

This commit removes the copying of the authorization header as it is not necessary and by not copying
it, we limit the amount of copies we make of this sensitive information.

Original commit: elastic/x-pack-elasticsearch@4e5ba4b4aa
This commit is contained in:
jaymode 2015-08-25 11:19:07 -04:00
parent 0e365a7670
commit d6eb2c8261
7 changed files with 12 additions and 38 deletions

View File

@ -6,7 +6,6 @@
package org.elasticsearch.shield.authc.activedirectory; package org.elasticsearch.shield.authc.activedirectory;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.ShieldSettingsFilter; import org.elasticsearch.shield.ShieldSettingsFilter;
import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.RealmConfig;
import org.elasticsearch.shield.authc.ldap.support.AbstractLdapRealm; import org.elasticsearch.shield.authc.ldap.support.AbstractLdapRealm;
@ -34,8 +33,8 @@ public class ActiveDirectoryRealm extends AbstractLdapRealm {
private final ClientSSLService clientSSLService; private final ClientSSLService clientSSLService;
@Inject @Inject
public Factory(ResourceWatcherService watcherService, RestController restController, ClientSSLService clientSSLService) { public Factory(ResourceWatcherService watcherService, ClientSSLService clientSSLService) {
super(ActiveDirectoryRealm.TYPE, restController); super(ActiveDirectoryRealm.TYPE);
this.watcherService = watcherService; this.watcherService = watcherService;
this.clientSSLService = clientSSLService; this.clientSSLService = clientSSLService;
} }

View File

@ -8,7 +8,6 @@ package org.elasticsearch.shield.authc.esusers;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.Realm; import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.RealmConfig;
@ -59,12 +58,11 @@ public class ESUsersRealm extends CachingUsernamePasswordRealm {
private final ResourceWatcherService watcherService; private final ResourceWatcherService watcherService;
@Inject @Inject
public Factory(Settings settings, Environment env, ResourceWatcherService watcherService, RestController restController) { public Factory(Settings settings, Environment env, ResourceWatcherService watcherService) {
super(TYPE, true); super(TYPE, true);
this.settings = settings; this.settings = settings;
this.env = env; this.env = env;
this.watcherService = watcherService; this.watcherService = watcherService;
restController.registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
} }
@Override @Override

View File

@ -8,7 +8,6 @@ package org.elasticsearch.shield.authc.ldap;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.ShieldSettingsFilter; import org.elasticsearch.shield.ShieldSettingsFilter;
import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.RealmConfig;
import org.elasticsearch.shield.authc.ldap.support.AbstractLdapRealm; import org.elasticsearch.shield.authc.ldap.support.AbstractLdapRealm;
@ -36,8 +35,8 @@ public class LdapRealm extends AbstractLdapRealm {
private final ClientSSLService clientSSLService; private final ClientSSLService clientSSLService;
@Inject @Inject
public Factory(ResourceWatcherService watcherService, RestController restController, ClientSSLService clientSSLService) { public Factory(ResourceWatcherService watcherService, ClientSSLService clientSSLService) {
super(TYPE, restController); super(TYPE);
this.watcherService = watcherService; this.watcherService = watcherService;
this.clientSSLService = clientSSLService; this.clientSSLService = clientSSLService;
} }

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.shield.authc.ldap.support; package org.elasticsearch.shield.authc.ldap.support;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.RealmConfig;
import org.elasticsearch.shield.authc.support.*; import org.elasticsearch.shield.authc.support.*;
@ -64,8 +63,8 @@ public abstract class AbstractLdapRealm extends CachingUsernamePasswordRealm {
public static abstract class Factory<R extends AbstractLdapRealm> extends UsernamePasswordRealm.Factory<R> { public static abstract class Factory<R extends AbstractLdapRealm> extends UsernamePasswordRealm.Factory<R> {
public Factory(String type, RestController restController) { public Factory(String type) {
super(type, false, restController); super(type, false);
} }
/** /**

View File

@ -5,15 +5,12 @@
*/ */
package org.elasticsearch.shield.authc.support; package org.elasticsearch.shield.authc.support;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.authc.AuthenticationToken; import org.elasticsearch.shield.authc.AuthenticationToken;
import org.elasticsearch.shield.authc.Realm; import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.RealmConfig;
import org.elasticsearch.transport.TransportMessage; import org.elasticsearch.transport.TransportMessage;
import static org.elasticsearch.shield.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER;
/** /**
* *
*/ */
@ -39,9 +36,8 @@ public abstract class UsernamePasswordRealm extends Realm<UsernamePasswordToken>
public static abstract class Factory<R extends UsernamePasswordRealm> extends Realm.Factory<R> { public static abstract class Factory<R extends UsernamePasswordRealm> extends Realm.Factory<R> {
protected Factory(String type, boolean internal, RestController restController) { protected Factory(String type, boolean internal) {
super(type, internal); super(type, internal);
restController.registerRelevantHeaders(BASIC_AUTH_HEADER);
} }
} }
} }

View File

@ -43,7 +43,6 @@ import static org.mockito.Mockito.*;
*/ */
public class ESUsersRealmTests extends ESTestCase { public class ESUsersRealmTests extends ESTestCase {
private RestController restController;
private Client client; private Client client;
private AdminClient adminClient; private AdminClient adminClient;
private FileUserPasswdStore userPasswdStore; private FileUserPasswdStore userPasswdStore;
@ -54,18 +53,11 @@ public class ESUsersRealmTests extends ESTestCase {
public void init() throws Exception { public void init() throws Exception {
client = mock(Client.class); client = mock(Client.class);
adminClient = mock(AdminClient.class); adminClient = mock(AdminClient.class);
restController = mock(RestController.class);
userPasswdStore = mock(FileUserPasswdStore.class); userPasswdStore = mock(FileUserPasswdStore.class);
userRolesStore = mock(FileUserRolesStore.class); userRolesStore = mock(FileUserRolesStore.class);
globalSettings = Settings.builder().put("path.home", createTempDir()).build(); globalSettings = Settings.builder().put("path.home", createTempDir()).build();
} }
@Test
public void testRestHeaderRegistration() {
new ESUsersRealm.Factory(Settings.EMPTY, mock(Environment.class), mock(ResourceWatcherService.class), restController);
verify(restController).registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
}
@Test @Test
public void testAuthenticate() throws Exception { public void testAuthenticate() throws Exception {
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true); when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
@ -134,11 +126,11 @@ public class ESUsersRealmTests extends ESTestCase {
} }
@Test @SuppressWarnings("unchecked") @Test @SuppressWarnings("unchecked")
public void testRestHeadersAreCopied() throws Exception { public void testAuthorizationHeaderIsNotCopied() throws Exception {
RestController restController = mock(RestController.class);
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings); RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
// the required header will be registered only if ESUsersRealm is actually used.
new ESUsersRealm(config, new UserPasswdStore(config), new UserRolesStore(config)); new ESUsersRealm(config, new UserPasswdStore(config), new UserRolesStore(config));
when(restController.relevantHeaders()).thenReturn(ImmutableSet.of(UsernamePasswordToken.BASIC_AUTH_HEADER)); when(restController.relevantHeaders()).thenReturn(ImmutableSet.<String>of());
when(client.admin()).thenReturn(adminClient); when(client.admin()).thenReturn(adminClient);
when(client.settings()).thenReturn(Settings.EMPTY); when(client.settings()).thenReturn(Settings.EMPTY);
when(client.headers()).thenReturn(Headers.EMPTY); when(client.headers()).thenReturn(Headers.EMPTY);
@ -163,7 +155,7 @@ public class ESUsersRealmTests extends ESTestCase {
when(restRequest.header(UsernamePasswordToken.BASIC_AUTH_HEADER)).thenReturn("foobar"); when(restRequest.header(UsernamePasswordToken.BASIC_AUTH_HEADER)).thenReturn("foobar");
RestChannel channel = mock(RestChannel.class); RestChannel channel = mock(RestChannel.class);
handler.handleRequest(restRequest, channel); handler.handleRequest(restRequest, channel);
assertThat((String) request.getHeader(UsernamePasswordToken.BASIC_AUTH_HEADER), Matchers.equalTo("foobar")); assertThat(request.getHeader(UsernamePasswordToken.BASIC_AUTH_HEADER), is(nullValue()));
} }
static class UserPasswdStore extends FileUserPasswdStore { static class UserPasswdStore extends FileUserPasswdStore {

View File

@ -6,7 +6,6 @@
package org.elasticsearch.shield.authc.ldap; package org.elasticsearch.shield.authc.ldap;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.shield.User; import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.RealmConfig;
import org.elasticsearch.shield.authc.ldap.support.LdapSearchScope; import org.elasticsearch.shield.authc.ldap.support.LdapSearchScope;
@ -36,14 +35,12 @@ public class LdapRealmTests extends LdapTestCase {
public static final String VALID_USERNAME = "Thomas Masterman Hardy"; public static final String VALID_USERNAME = "Thomas Masterman Hardy";
public static final String PASSWORD = "pass"; public static final String PASSWORD = "pass";
private RestController restController;
private ThreadPool threadPool; private ThreadPool threadPool;
private ResourceWatcherService resourceWatcherService; private ResourceWatcherService resourceWatcherService;
private Settings globalSettings; private Settings globalSettings;
@Before @Before
public void init() throws Exception { public void init() throws Exception {
restController = mock(RestController.class);
threadPool = new ThreadPool("ldap realm tests"); threadPool = new ThreadPool("ldap realm tests");
resourceWatcherService = new ResourceWatcherService(Settings.EMPTY, threadPool); resourceWatcherService = new ResourceWatcherService(Settings.EMPTY, threadPool);
globalSettings = Settings.builder().put("path.home", createTempDir()).build(); globalSettings = Settings.builder().put("path.home", createTempDir()).build();
@ -55,12 +52,6 @@ public class LdapRealmTests extends LdapTestCase {
terminate(threadPool); terminate(threadPool);
} }
@Test
public void testRestHeaderRegistration() {
new LdapRealm.Factory(resourceWatcherService, restController, null);
verify(restController).registerRelevantHeaders(UsernamePasswordToken.BASIC_AUTH_HEADER);
}
@Test @Test
public void testAuthenticate_SubTreeGroupSearch() throws Exception { public void testAuthenticate_SubTreeGroupSearch() throws Exception {
String groupSearchBase = "o=sevenSeas"; String groupSearchBase = "o=sevenSeas";