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:
parent
bf73ba3665
commit
ad02ec4609
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue