Bläddra i källkod

Fix NPE in CachingUsernamePasswordRealm (#36953)

This commit fixes an NPE in the CachingUsernamePasswordRealm when the
cache is disabled.
Jason Tedor 6 år sedan
förälder
incheckning
7e2bb9c1aa

+ 3 - 1
x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java

@@ -119,6 +119,7 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm
      * @param listener to be called at completion
      */
     private void authenticateWithCache(UsernamePasswordToken token, ActionListener<AuthenticationResult> listener) {
+        assert cache != null;
         try {
             final AtomicBoolean authenticationInCache = new AtomicBoolean(true);
             final ListenableFuture<UserWithHash> listenableCacheEntry = cache.computeIfAbsent(token.principal(), k -> {
@@ -200,7 +201,7 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm
     }
 
     protected int getCacheSize() {
-        return cache.count();
+        return cache == null ? -1 : cache.count();
     }
 
     protected abstract void doAuthenticate(UsernamePasswordToken token, ActionListener<AuthenticationResult> listener);
@@ -221,6 +222,7 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm
     }
 
     private void lookupWithCache(String username, ActionListener<User> listener) {
+        assert cache != null;
         try {
             final AtomicBoolean lookupInCache = new AtomicBoolean(true);
             final ListenableFuture<UserWithHash> listenableCacheEntry = cache.computeIfAbsent(username, key -> {

+ 29 - 0
x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealmTests.java

@@ -92,30 +92,59 @@ public class CachingUsernamePasswordRealmTests extends ESTestCase {
         assertThat(realm.cacheHasher, sameInstance(Hasher.resolve(cachingHashAlgo)));
     }
 
+    public void testCacheSizeWhenCacheDisabled() {
+        final RealmConfig.RealmIdentifier identifier = new RealmConfig.RealmIdentifier("caching", "test_realm");
+        final Settings settings = Settings.builder()
+                .put(globalSettings)
+                .put(RealmSettings.getFullSettingKey(identifier, CachingUsernamePasswordRealmSettings.CACHE_TTL_SETTING), -1)
+                .build();
+
+        final RealmConfig config =
+                new RealmConfig(identifier, settings, TestEnvironment.newEnvironment(globalSettings), new ThreadContext(Settings.EMPTY));
+        final CachingUsernamePasswordRealm realm = new CachingUsernamePasswordRealm(config, threadPool) {
+            @Override
+            protected void doAuthenticate(UsernamePasswordToken token, ActionListener<AuthenticationResult> listener) {
+                listener.onResponse(AuthenticationResult.success(new User("username", new String[]{"r1", "r2", "r3"})));
+            }
+
+            @Override
+            protected void doLookupUser(String username, ActionListener<User> listener) {
+                listener.onFailure(new UnsupportedOperationException("this method should not be called"));
+            }
+        };
+        assertThat(realm.getCacheSize(), equalTo(-1));
+    }
+
     public void testAuthCache() {
         AlwaysAuthenticateCachingRealm realm = new AlwaysAuthenticateCachingRealm(globalSettings, threadPool);
         SecureString pass = new SecureString("pass");
         PlainActionFuture<AuthenticationResult> future = new PlainActionFuture<>();
         realm.authenticate(new UsernamePasswordToken("a", pass), future);
         future.actionGet();
+        assertThat(realm.getCacheSize(), equalTo(1));
         future = new PlainActionFuture<>();
         realm.authenticate(new UsernamePasswordToken("b", pass), future);
         future.actionGet();
+        assertThat(realm.getCacheSize(), equalTo(2));
         future = new PlainActionFuture<>();
         realm.authenticate(new UsernamePasswordToken("c", pass), future);
         future.actionGet();
+        assertThat(realm.getCacheSize(), equalTo(3));
 
         assertThat(realm.authInvocationCounter.intValue(), is(3));
 
         future = new PlainActionFuture<>();
         realm.authenticate(new UsernamePasswordToken("a", pass), future);
         future.actionGet();
+        assertThat(realm.getCacheSize(), equalTo(3));
         future = new PlainActionFuture<>();
         realm.authenticate(new UsernamePasswordToken("b", pass), future);
         future.actionGet();
+        assertThat(realm.getCacheSize(), equalTo(3));
         future = new PlainActionFuture<>();
         realm.authenticate(new UsernamePasswordToken("c", pass), future);
         future.actionGet();
+        assertThat(realm.getCacheSize(), equalTo(3));
 
         assertThat(realm.authInvocationCounter.intValue(), is(3));
         assertThat(realm.lookupInvocationCounter.intValue(), is(0));