Added the realm type to the audit trail logs for failed authentication

- Also introduced an option to disable esusers auth (such that if users configured ldap, the audit trails won't get cluttered by failed authentication in esusers
 - Moved the realms initialization to a dedicated Realms class
 - Also introduce an option to completely disable shield while keeping the installed plugin and its settings

Original commit: elastic/x-pack-elasticsearch@b554ad5ba7
This commit is contained in:
uboness 2014-08-08 18:27:01 +02:00
parent bf73ba3665
commit ad02ec4609
10 changed files with 83 additions and 21 deletions

View File

@ -29,11 +29,17 @@ public class SecurityModule extends AbstractModule implements SpawnModules {
@Override
public Iterable<? extends Module> spawnModules() {
// dont spawn module in client mode
// don't spawn module in client mode
if (settings.getAsBoolean("node.client", false)) {
return ImmutableList.of();
}
// don't spawn modules if shield is explicitly disabled
if (!settings.getComponentSettings(SecurityModule.class).getAsBoolean("enabled", true)) {
return ImmutableList.of();
}
return ImmutableList.of(
Modules.createModule(AuthenticationModule.class, settings),
Modules.createModule(AuthorizationModule.class, settings),

View File

@ -20,7 +20,7 @@ public interface AuditTrail {
}
@Override
public void authenticationFailed(AuthenticationToken token, String action, TransportRequest request) {
public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportRequest request) {
}
@Override
@ -34,7 +34,7 @@ public interface AuditTrail {
void anonymousAccess(String action, TransportRequest request);
void authenticationFailed(AuthenticationToken token, String action, TransportRequest request);
void authenticationFailed(String realm, AuthenticationToken token, String action, TransportRequest request);
void accessGranted(User user, String action, TransportRequest request);

View File

@ -35,9 +35,9 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail {
}
@Override
public void authenticationFailed(AuthenticationToken token, String action, TransportRequest request) {
public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportRequest request) {
for (int i = 0; i < auditTrails.length; i++) {
auditTrails[i].authenticationFailed(token, action, request);
auditTrails[i].authenticationFailed(realm, token, action, request);
}
}

View File

@ -33,11 +33,11 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
}
@Override
public void authenticationFailed(AuthenticationToken token, String action, TransportRequest request) {
public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportRequest request) {
if (logger.isDebugEnabled()) {
logger.info("AUTHENTICATION_FAILED\thost=[{}], action=[{}], principal=[{}], request=[{}]", request.remoteAddress(), action, token.principal(), request);
logger.info("AUTHENTICATION_FAILED\thost=[{}], realm=[{}], action=[{}], principal=[{}], request=[{}]", request.remoteAddress(), realm, action, token.principal(), request);
} else {
logger.info("AUTHENTICATION_FAILED\thost=[{}], action=[{}], principal=[{}]", request.remoteAddress(), action, token.principal());
logger.info("AUTHENTICATION_FAILED\thost=[{}], realm=[{}], action=[{}], principal=[{}]", request.remoteAddress(), realm, action, token.principal());
}
}

View File

@ -28,9 +28,11 @@ public class AuthenticationModule extends AbstractModule implements SpawnModules
@Override
public Iterable<? extends Module> spawnModules() {
ImmutableList.Builder<? extends Module> modules = ImmutableList.builder();
modules.add(Modules.createModule(ESUsersModule.class, settings));
if (ESUsersModule.enabled(settings)) {
modules.add(new ESUsersModule());
}
if (LdapModule.enabled(settings)) {
modules.add(Modules.createModule(LdapModule.class, settings));
modules.add(new LdapModule());
}
return modules.build();
}

View File

@ -11,8 +11,6 @@ import org.elasticsearch.common.inject.internal.Nullable;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.AuditTrail;
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
import org.elasticsearch.shield.authc.ldap.LdapRealm;
import org.elasticsearch.transport.TransportRequest;
/**
@ -24,11 +22,9 @@ public class InternalAuthenticationService extends AbstractComponent implements
private final AuditTrail auditTrail;
@Inject
public InternalAuthenticationService(Settings settings, ESUsersRealm esUsersRealm, @Nullable LdapRealm ldapRealm, @Nullable AuditTrail auditTrail) {
public InternalAuthenticationService(Settings settings, Realms realms, @Nullable AuditTrail auditTrail) {
super(settings);
this.realms = ldapRealm != null ?
new Realm[] { esUsersRealm, ldapRealm } :
new Realm[] { esUsersRealm };
this.realms = realms.realms();
this.auditTrail = auditTrail;
}
@ -49,14 +45,14 @@ public class InternalAuthenticationService extends AbstractComponent implements
*/
@Override
public User authenticate(String action, TransportRequest request) throws AuthenticationException {
for (int i = 0; i < realms.length; i++) {
AuthenticationToken token = realms[i].token(request);
for (Realm realm : realms) {
AuthenticationToken token = realm.token(request);
if (token != null) {
User user = realms[i].authenticate(token);
User user = realm.authenticate(token);
if (user != null) {
return user;
} else if (auditTrail != null) {
auditTrail.authenticationFailed(token, action, request);
auditTrail.authenticationFailed(realm.type(), token, action, request);
}
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.shield.authc;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.internal.Nullable;
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
import org.elasticsearch.shield.authc.ldap.LdapRealm;
import java.util.ArrayList;
import java.util.List;
/**
* Serves as a realms registry (also responsible for ordering the realms appropriately)
*/
public class Realms {
private final Realm[] realms;
@Inject
public Realms(@Nullable ESUsersRealm esusers, @Nullable LdapRealm ldap) {
List<Realm> realms = new ArrayList<>();
if (esusers != null) {
realms.add(esusers);
}
if (ldap != null) {
realms.add(ldap);
}
this.realms = realms.toArray(new Realm[realms.size()]);
}
Realm[] realms() {
return realms;
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.shield.authc.esusers;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.authc.support.UserPasswdStore;
import org.elasticsearch.shield.authc.support.UserRolesStore;
@ -16,6 +17,10 @@ import static org.elasticsearch.common.inject.name.Names.named;
*/
public class ESUsersModule extends AbstractModule {
public static boolean enabled(Settings settings) {
return settings.getComponentSettings(ESUsersModule.class).getAsBoolean("enabled", true);
}
@Override
protected void configure() {
bind(ESUsersRealm.class).asEagerSingleton();

View File

@ -15,7 +15,7 @@ public class LdapModule extends AbstractModule {
public static boolean enabled(Settings settings) {
Settings ldapSettings = settings.getComponentSettings(LdapModule.class);
return ldapSettings != null;
return ldapSettings != null && ldapSettings.getAsBoolean("enabled", true);
}
@Override

View File

@ -47,6 +47,19 @@ public class ESUsersModuleTests extends ElasticsearchTestCase {
assertThat(realm.userRolesStore, instanceOf(FileUserRolesStore.class));
}
@Test
public void testEnabled() throws Exception {
assertThat(ESUsersModule.enabled(ImmutableSettings.EMPTY), is(true));
Settings settings = ImmutableSettings.builder()
.put("shield.authc.esusers.enabled", false)
.build();
assertThat(ESUsersModule.enabled(settings), is(false));
settings = ImmutableSettings.builder()
.put("shield.authc.esusers.enabled", true)
.build();
assertThat(ESUsersModule.enabled(settings), is(true));
}
public static class TestModule extends AbstractModule {
final Path users;
@ -70,4 +83,5 @@ public class ESUsersModuleTests extends ElasticsearchTestCase {
bind(ResourceWatcherService.class).asEagerSingleton();
}
}
}