mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-30 20:08:29 +00:00
Allow User/Password realms to disable authc (#34033)
The "lookupUser" method on a realm facilitates the "run-as" and "authorization_realms" features. This commit allows a realm to be used for "lookup only", in which case the "authenticate" method (and associated token methods) are disabled. It does this through the introduction of a new "authentication.enabled" setting, which defaults to true.
This commit is contained in:
parent
6608992523
commit
63dbd1dce0
docs/reference/settings
x-pack/plugin
core/src/main/java/org/elasticsearch/xpack/core/security/authc
esnative
file
ldap
support
security/src
main/java/org/elasticsearch/xpack/security/authc/support
test/java/org/elasticsearch/xpack/security/authc/support
@ -204,6 +204,11 @@ cache at any given time. Defaults to 100,000.
|
||||
in-memory cached user credentials. For possible values, see <<cache-hash-algo>>.
|
||||
Defaults to `ssha256`.
|
||||
|
||||
`authentication.enabled`:: If set to `false`, disables authentication support in
|
||||
this realm, so that it only supports user lookups.
|
||||
(See the {xpack-ref}/run-as-privilege.html[run as] and
|
||||
{stack-ov}/realm-chains.html#authorization_realms[authorization realms] features).
|
||||
Defaults to `true`.
|
||||
|
||||
[[ref-users-settings]]
|
||||
|
||||
@ -228,6 +233,12 @@ Defaults to 100,000.
|
||||
(Expert Setting) The hashing algorithm that is used for the in-memory cached
|
||||
user credentials. See <<cache-hash-algo>>. Defaults to `ssha256`.
|
||||
|
||||
`authentication.enabled`:: If set to `false`, disables authentication support in
|
||||
this realm, so that it only supports user lookups.
|
||||
(See the {xpack-ref}/run-as-privilege.html[run as] and
|
||||
{stack-ov}/realm-chains.html#authorization_realms[authorization realms] features).
|
||||
Defaults to `true`.
|
||||
|
||||
[[ref-ldap-settings]]
|
||||
[float]
|
||||
===== LDAP realm settings
|
||||
@ -490,6 +501,12 @@ Defaults to `100000`.
|
||||
(Expert Setting) Specifies the hashing algorithm that is used for the
|
||||
in-memory cached user credentials. See <<cache-hash-algo>>. Defaults to `ssha256`.
|
||||
|
||||
`authentication.enabled`:: If set to `false`, disables authentication support in
|
||||
this realm, so that it only supports user lookups.
|
||||
(See the {xpack-ref}/run-as-privilege.html[run as] and
|
||||
{stack-ov}/realm-chains.html#authorization_realms[authorization realms] features).
|
||||
Defaults to `true`.
|
||||
|
||||
[[ref-ad-settings]]
|
||||
[float]
|
||||
===== Active Directory realm settings
|
||||
@ -731,6 +748,12 @@ Defaults to `100000`.
|
||||
(Expert Setting) Specifies the hashing algorithm that is used for
|
||||
the in-memory cached user credentials. See <<cache-hash-algo>>. Defaults to `ssha256`.
|
||||
|
||||
`authentication.enabled`:: If set to `false`, disables authentication support in
|
||||
this realm, so that it only supports user lookups.
|
||||
(See the {xpack-ref}/run-as-privilege.html[run as] and
|
||||
{stack-ov}/realm-chains.html#authorization_realms[authorization realms] features).
|
||||
Defaults to `true`.
|
||||
|
||||
`follow_referrals`::
|
||||
If set to `true` {security} follows referrals returned by the LDAP server.
|
||||
Referrals are URLs returned by the server that are to be used to continue the
|
||||
|
@ -19,6 +19,6 @@ public final class NativeRealmSettings {
|
||||
* @return The {@link Setting setting configuration} for this realm type
|
||||
*/
|
||||
public static Set<Setting<?>> getSettings() {
|
||||
return CachingUsernamePasswordRealmSettings.getCachingSettings();
|
||||
return CachingUsernamePasswordRealmSettings.getSettings();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ public final class FileRealmSettings {
|
||||
* @return The {@link Setting setting configuration} for this realm type
|
||||
*/
|
||||
public static Set<Setting<?>> getSettings() {
|
||||
return CachingUsernamePasswordRealmSettings.getCachingSettings();
|
||||
return CachingUsernamePasswordRealmSettings.getSettings();
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public final class LdapRealmSettings {
|
||||
*/
|
||||
public static Set<Setting<?>> getSettings(String type) {
|
||||
Set<Setting<?>> settings = new HashSet<>();
|
||||
settings.addAll(CachingUsernamePasswordRealmSettings.getCachingSettings());
|
||||
settings.addAll(CachingUsernamePasswordRealmSettings.getSettings());
|
||||
settings.addAll(CompositeRoleMapperSettings.getSettings());
|
||||
settings.add(LdapRealmSettings.EXECUTION_TIMEOUT);
|
||||
if (AD_TYPE.equals(type)) {
|
||||
|
@ -21,12 +21,15 @@ public final class CachingUsernamePasswordRealmSettings {
|
||||
public static final Setting<Integer> CACHE_MAX_USERS_SETTING = Setting.intSetting("cache.max_users", DEFAULT_MAX_USERS,
|
||||
Setting.Property.NodeScope);
|
||||
|
||||
public static final Setting<Boolean> AUTHC_ENABLED_SETTING = Setting.boolSetting("authentication.enabled", true,
|
||||
Setting.Property.NodeScope);
|
||||
|
||||
private CachingUsernamePasswordRealmSettings() {}
|
||||
|
||||
/**
|
||||
* Returns the {@link Setting setting configuration} that is common for all caching realms
|
||||
*/
|
||||
public static Set<Setting<?>> getCachingSettings() {
|
||||
return new HashSet<>(Arrays.asList(CACHE_HASH_ALGO_SETTING, CACHE_TTL_SETTING, CACHE_MAX_USERS_SETTING));
|
||||
public static Set<Setting<?>> getSettings() {
|
||||
return new HashSet<>(Arrays.asList(CACHE_HASH_ALGO_SETTING, CACHE_TTL_SETTING, CACHE_MAX_USERS_SETTING, AUTHC_ENABLED_SETTING));
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import org.elasticsearch.common.cache.CacheBuilder;
|
||||
import org.elasticsearch.common.settings.SecureString;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.util.concurrent.ListenableFuture;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
|
||||
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
|
||||
@ -30,6 +31,7 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm
|
||||
|
||||
private final Cache<String, ListenableFuture<UserWithHash>> cache;
|
||||
private final ThreadPool threadPool;
|
||||
private final boolean authenticationEnabled;
|
||||
final Hasher cacheHasher;
|
||||
|
||||
protected CachingUsernamePasswordRealm(String type, RealmConfig config, ThreadPool threadPool) {
|
||||
@ -45,6 +47,7 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm
|
||||
} else {
|
||||
cache = null;
|
||||
}
|
||||
this.authenticationEnabled = CachingUsernamePasswordRealmSettings.AUTHC_ENABLED_SETTING.get(config.settings());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -63,15 +66,34 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsernamePasswordToken token(ThreadContext threadContext) {
|
||||
if (authenticationEnabled == false) {
|
||||
return null;
|
||||
}
|
||||
return super.token(threadContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(AuthenticationToken token) {
|
||||
return authenticationEnabled && super.supports(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user exists in the cache (keyed by the principle name), then the password is validated
|
||||
* against a hash also stored in the cache. Otherwise the subclass authenticates the user via
|
||||
* doAuthenticate
|
||||
* doAuthenticate.
|
||||
* This method will respond with {@link AuthenticationResult#notHandled()} if
|
||||
* {@link CachingUsernamePasswordRealmSettings#AUTHC_ENABLED_SETTING authentication is not enabled}.
|
||||
* @param authToken The authentication token
|
||||
* @param listener to be called at completion
|
||||
*/
|
||||
@Override
|
||||
public final void authenticate(AuthenticationToken authToken, ActionListener<AuthenticationResult> listener) {
|
||||
if (authenticationEnabled == false) {
|
||||
listener.onResponse(AuthenticationResult.notHandled());
|
||||
return;
|
||||
}
|
||||
final UsernamePasswordToken token = (UsernamePasswordToken) authToken;
|
||||
try {
|
||||
if (cache == null) {
|
||||
|
@ -11,6 +11,7 @@ import org.elasticsearch.common.settings.SecureString;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.env.TestEnvironment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.SecuritySettingsSourceField;
|
||||
@ -62,7 +63,7 @@ public class CachingUsernamePasswordRealmTests extends ESTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSettings() throws Exception {
|
||||
public void testCacheSettings() throws Exception {
|
||||
String cachingHashAlgo = Hasher.values()[randomIntBetween(0, Hasher.values().length - 1)].name().toLowerCase(Locale.ROOT);
|
||||
int maxUsers = randomIntBetween(10, 100);
|
||||
TimeValue ttl = TimeValue.timeValueMinutes(randomIntBetween(10, 20));
|
||||
@ -560,6 +561,33 @@ public class CachingUsernamePasswordRealmTests extends ESTestCase {
|
||||
assertEquals(1, lookupCounter.get());
|
||||
}
|
||||
|
||||
public void testAuthenticateDisabled() throws Exception {
|
||||
final Settings settings = Settings.builder()
|
||||
.put(CachingUsernamePasswordRealmSettings.AUTHC_ENABLED_SETTING.getKey(), false)
|
||||
.build();
|
||||
final Environment env = TestEnvironment.newEnvironment(globalSettings);
|
||||
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
||||
final RealmConfig config = new RealmConfig("test_authentication_disabled", settings, globalSettings, env, threadContext);
|
||||
final AlwaysAuthenticateCachingRealm realm = new AlwaysAuthenticateCachingRealm(config, threadPool);
|
||||
|
||||
final UsernamePasswordToken token = new UsernamePasswordToken("phil", new SecureString("tahiti"));
|
||||
UsernamePasswordToken.putTokenHeader(threadContext, token);
|
||||
assertThat(realm.token(threadContext), nullValue());
|
||||
assertThat(realm.supports(token), equalTo(false));
|
||||
|
||||
PlainActionFuture<AuthenticationResult> authFuture = new PlainActionFuture<>();
|
||||
realm.authenticate(token, authFuture);
|
||||
final AuthenticationResult authResult = authFuture.get();
|
||||
assertThat(authResult.isAuthenticated(), equalTo(false));
|
||||
assertThat(authResult.getStatus(), equalTo(AuthenticationResult.Status.CONTINUE));
|
||||
|
||||
PlainActionFuture<User> lookupFuture = new PlainActionFuture<>();
|
||||
realm.lookupUser(token.principal(), lookupFuture);
|
||||
final User user = lookupFuture.get();
|
||||
assertThat(user, notNullValue());
|
||||
assertThat(user.principal(), equalTo(token.principal()));
|
||||
}
|
||||
|
||||
static class FailingAuthenticationRealm extends CachingUsernamePasswordRealm {
|
||||
|
||||
FailingAuthenticationRealm(Settings settings, Settings global, ThreadPool threadPool) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user