From 37d145be43129fdf8e3030a252f37f36ce6c55ef Mon Sep 17 00:00:00 2001 From: Henrik Nyman Date: Mon, 1 Oct 2018 16:34:25 +0200 Subject: [PATCH] Fix more tests - Better handling of `null` credentials - Fix credentials handling in plugin cacheable authentication info - Add auth token matcher to test utils --- .../kernel/api/security/UserManager.java | 10 +++- .../java/org/neo4j/test/AuthTokenUtil.java | 51 ++++++++++++++++--- .../security/auth/BasicAuthManager.java | 10 +++- .../security/auth/BasicAuthManagerTest.java | 2 +- .../rest/dbms/AuthorizationFilterTest.java | 12 ++--- .../auth/EnterpriseUserManager.java | 10 +++- .../auth/InternalFlatFileRealm.java | 11 +++- .../enterprise/auth/plugin/PluginRealm.java | 17 +++++-- .../auth/plugin/PluginShiroAuthToken.java | 18 ++++++- .../enterprise/auth/ShiroAuthTokenTest.java | 18 ++++--- .../bolt/BoltInitChangePasswordTest.java | 4 +- .../plugin/TestCredentialsOnlyPlugin.java | 4 +- 12 files changed, 130 insertions(+), 37 deletions(-) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/security/UserManager.java b/community/kernel/src/main/java/org/neo4j/kernel/api/security/UserManager.java index 916a287973398..ac8e712cf0a7c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/security/UserManager.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/security/UserManager.java @@ -56,7 +56,10 @@ void setUserPassword( String username, byte[] password, boolean requirePasswordC @Override public User newUser( String username, byte[] initialPassword, boolean requirePasswordChange ) { - Arrays.fill( initialPassword, (byte) 0 ); + if ( initialPassword != null ) + { + Arrays.fill( initialPassword, (byte) 0 ); + } return null; } @@ -81,7 +84,10 @@ public User silentlyGetUser( String username ) @Override public void setUserPassword( String username, byte[] password, boolean requirePasswordChange ) { - Arrays.fill( password, (byte) 0 ); + if ( password != null ) + { + Arrays.fill( password, (byte) 0 ); + } } @Override diff --git a/community/kernel/src/test/java/org/neo4j/test/AuthTokenUtil.java b/community/kernel/src/test/java/org/neo4j/test/AuthTokenUtil.java index b17e8c7551085..5210c1cf64f62 100644 --- a/community/kernel/src/test/java/org/neo4j/test/AuthTokenUtil.java +++ b/community/kernel/src/test/java/org/neo4j/test/AuthTokenUtil.java @@ -19,6 +19,8 @@ */ package org.neo4j.test; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; import org.mockito.ArgumentMatcher; import java.io.Serializable; @@ -35,13 +37,21 @@ public class AuthTokenUtil { - public static boolean matches( Map expected, Map actual ) + @SuppressWarnings( "unchecked" ) + public static boolean matches( Map expected, Object actualObject ) { - if ( expected == null || actual == null ) + if ( expected == null || actualObject == null ) { - return expected == actual; + return expected == actualObject; } + if ( !(actualObject instanceof Map) ) + { + return false; + } + + Map actual = (Map) actualObject; + if ( expected.size() != actual.size() ) { return false; @@ -61,9 +71,9 @@ public static boolean matches( Map expected, Map a return false; } } - else if ( expectedValue == null ^ actualValue == null ) + else if ( expectedValue == null || actualValue == null ) { - return false; + return expectedValue == actualValue; } else if ( !expectedValue.equals( actualValue ) ) { @@ -92,6 +102,33 @@ public static void assertAuthTokenMatches( Map expected, Map> + { + private final Map expectedValue; + + public AuthTokenMatcher( Map expectedValue ) + { + this.expectedValue = expectedValue; + } + + @Override + public boolean matches( Object o ) + { + return AuthTokenUtil.matches( expectedValue, o ); + } + + @Override + public void describeTo( Description description ) + { + description.appendValue( this.expectedValue ); + } + } + + public static AuthTokenMatcher authTokenMatcher( Map authToken ) + { + return new AuthTokenMatcher( authToken ); + } + public static class AuthTokenArgumentMatcher implements ArgumentMatcher>, Serializable { @@ -109,11 +146,11 @@ public boolean matches( Map actual ) public String toString() { - return "authTokenMatcher(" + wanted + ")"; + return "authTokenArgumentMatcher(" + wanted + ")"; } } - public static Map authTokenMatcher( Map authToken ) + public static Map authTokenArgumentMatcher( Map authToken ) { mockingProgress().getArgumentMatcherStorage().reportMatcher( new AuthTokenArgumentMatcher( authToken ) ); return null; diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java b/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java index b4dd0dea87526..1c7f908d2b86c 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java @@ -164,7 +164,10 @@ public User newUser( String username, byte[] initialPassword, boolean requirePas finally { // Clear password - Arrays.fill( initialPassword, (byte) 0 ); + if ( initialPassword != null ) + { + Arrays.fill( initialPassword, (byte) 0 ); + } } } @@ -222,7 +225,10 @@ public void setUserPassword( String username, byte[] password, boolean requirePa finally { // Clear password - Arrays.fill( password, (byte) 0 ); + if ( password != null ) + { + Arrays.fill( password, (byte) 0 ); + } } } diff --git a/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java b/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java index 05326814f7aae..c3083b2b765b1 100644 --- a/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java +++ b/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java @@ -396,7 +396,7 @@ protected AuthManager authManager() public static byte[] password( String passwordString ) { - return passwordString.getBytes( StandardCharsets.UTF_8 ); + return passwordString != null ? passwordString.getBytes( StandardCharsets.UTF_8 ) : null; } public static byte[] clearedPasswordWithSameLenghtAs( String passwordString ) diff --git a/community/server/src/test/java/org/neo4j/server/rest/dbms/AuthorizationFilterTest.java b/community/server/src/test/java/org/neo4j/server/rest/dbms/AuthorizationFilterTest.java index 7c096e9ded9a3..bbe1c8bbb600e 100644 --- a/community/server/src/test/java/org/neo4j/server/rest/dbms/AuthorizationFilterTest.java +++ b/community/server/src/test/java/org/neo4j/server/rest/dbms/AuthorizationFilterTest.java @@ -52,7 +52,7 @@ import static org.neo4j.internal.kernel.api.security.LoginContext.AUTH_DISABLED; import static org.neo4j.logging.AssertableLogProvider.inLog; import static org.neo4j.server.security.auth.SecurityTestUtils.authToken; -import static org.neo4j.test.AuthTokenUtil.authTokenMatcher; +import static org.neo4j.test.AuthTokenUtil.authTokenArgumentMatcher; public class AuthorizationFilterTest { @@ -176,7 +176,7 @@ public void shouldNotAuthorizeInvalidCredentials() throws Exception when( servletRequest.getContextPath() ).thenReturn( "/db/data" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); when( servletRequest.getRemoteAddr() ).thenReturn( "remote_ip_address" ); - when( authManager.login( authTokenMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); + when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.FAILURE ); @@ -206,7 +206,7 @@ public void shouldAuthorizeWhenPasswordChangeRequiredForWhitelistedPath() throws when( servletRequest.getMethod() ).thenReturn( "GET" ); when( servletRequest.getContextPath() ).thenReturn( "/user/foo" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); - when( authManager.login( authTokenMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); + when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.PASSWORD_CHANGE_REQUIRED ); @@ -231,7 +231,7 @@ public void shouldNotAuthorizeWhenPasswordChangeRequired() throws Exception when( servletRequest.getRequestURL() ).thenReturn( new StringBuffer( "http://bar.baz:7474/db/data/" ) ); when( servletRequest.getRequestURI() ).thenReturn( "/db/data/" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); - when( authManager.login( authTokenMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); + when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.PASSWORD_CHANGE_REQUIRED ); @@ -261,7 +261,7 @@ public void shouldNotAuthorizeWhenTooManyAttemptsMade() throws Exception when( servletRequest.getMethod() ).thenReturn( "GET" ); when( servletRequest.getContextPath() ).thenReturn( "/db/data" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); - when( authManager.login( authTokenMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); + when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.TOO_MANY_ATTEMPTS ); @@ -290,7 +290,7 @@ public void shouldAuthorizeWhenValidCredentialsSupplied() throws Exception when( servletRequest.getMethod() ).thenReturn( "GET" ); when( servletRequest.getContextPath() ).thenReturn( "/db/data" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); - when( authManager.login( authTokenMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); + when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.SUCCESS ); diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java index 1187a4057c1aa..6f7051c78493a 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java @@ -145,7 +145,10 @@ public Set silentlyGetUsernamesForRole( String roleName ) @Override public User newUser( String username, byte[] initialPassword, boolean requirePasswordChange ) { - Arrays.fill( initialPassword, (byte) 0 ); + if ( initialPassword != null ) + { + Arrays.fill( initialPassword, (byte) 0 ); + } return null; } @@ -170,7 +173,10 @@ public User silentlyGetUser( String username ) @Override public void setUserPassword( String username, byte[] password, boolean requirePasswordChange ) { - Arrays.fill( password, (byte) 0 ); + if ( password != null ) + { + Arrays.fill( password, (byte) 0 ); + } } @Override diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java index e3b96cb8cf063..345765fa914ed 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java @@ -482,7 +482,10 @@ public User newUser( String username, byte[] initialPassword, boolean requirePas finally { // Clear password - Arrays.fill( initialPassword, (byte) 0 ); + if ( initialPassword != null ) + { + Arrays.fill( initialPassword, (byte) 0 ); + } } } @@ -676,7 +679,11 @@ public void setUserPassword( String username, byte[] password, boolean requirePa } finally { - Arrays.fill( password, (byte) 0 ); + // Clear password + if ( password != null ) + { + Arrays.fill( password, (byte) 0 ); + } } } diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginRealm.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginRealm.java index 33332c28e9530..4e2227942ab24 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginRealm.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginRealm.java @@ -381,7 +381,11 @@ public boolean doCredentialsMatch( AuthenticationToken token, AuthenticationInfo finally { // Clear credentials - Arrays.fill( pluginApiAuthToken.credentials(), (char) 0 ); + char[] credentials = pluginApiAuthToken.credentials(); + if ( credentials != null ) + { + Arrays.fill( credentials, (char) 0 ); + } } } catch ( InvalidAuthTokenException e ) @@ -392,8 +396,15 @@ public boolean doCredentialsMatch( AuthenticationToken token, AuthenticationInfo else if ( info.getCredentials() != null ) { // Authentication info is originating from a CacheableAuthenticationInfo or a CacheableAuthInfo - return secureHasher.getHashedCredentialsMatcher() - .doCredentialsMatch( PluginShiroAuthToken.of( token ), info ); + PluginShiroAuthToken pluginShiroAuthToken = PluginShiroAuthToken.of( token ); + try + { + return secureHasher.getHashedCredentialsMatcher().doCredentialsMatch( pluginShiroAuthToken, info ); + } + finally + { + pluginShiroAuthToken.clearCredentials(); + } } else { diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginShiroAuthToken.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginShiroAuthToken.java index 33dec8f9b34b5..bc9eb6f49e834 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginShiroAuthToken.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/plugin/PluginShiroAuthToken.java @@ -24,6 +24,9 @@ import org.apache.shiro.authc.AuthenticationToken; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Map; import org.neo4j.server.security.enterprise.auth.ShiroAuthToken; @@ -35,15 +38,28 @@ */ public class PluginShiroAuthToken extends ShiroAuthToken { + private final char[] credentials; + private PluginShiroAuthToken( Map authTokenMap ) { super( authTokenMap ); + // Convert credentials UTF8 byte[] to char[] (this should not create any intermediate copies) + byte[] credentialsBytes = (byte[]) super.getCredentials(); + credentials = credentialsBytes != null ? StandardCharsets.UTF_8.decode( ByteBuffer.wrap( credentialsBytes ) ).array() : null; } @Override public Object getCredentials() { - return ((String) super.getCredentials()).toCharArray(); + return credentials; + } + + void clearCredentials() + { + if ( credentials != null ) + { + Arrays.fill( credentials, (char) 0 ); + } } public static PluginShiroAuthToken of( ShiroAuthToken shiroAuthToken ) diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthTokenTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthTokenTest.java index f3558045ae64e..895c0c5544281 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthTokenTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthTokenTest.java @@ -33,6 +33,8 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.neo4j.helpers.collection.MapUtil.map; +import static org.neo4j.server.security.auth.BasicAuthManagerTest.password; +import static org.neo4j.test.AuthTokenUtil.authTokenMatcher; public class ShiroAuthTokenTest { @@ -45,7 +47,7 @@ public void shouldSupportBasicAuthToken() throws Exception ShiroAuthToken token = new ShiroAuthToken( AuthToken.newBasicAuthToken( USERNAME, PASSWORD ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME ) ) ); testTokenSupportsRealm( token, true, "unknown", "native", "ldap" ); } @@ -56,7 +58,7 @@ public void shouldSupportBasicAuthTokenWithEmptyRealm() throws Exception ShiroAuthToken token = new ShiroAuthToken( AuthToken.newBasicAuthToken( USERNAME, PASSWORD, "" ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME, AuthToken.REALM_KEY, "" ) ) ); testTokenSupportsRealm( token, true, "unknown", "native", "ldap" ); } @@ -67,7 +69,7 @@ public void shouldSupportBasicAuthTokenWithNullRealm() throws Exception ShiroAuthToken token = new ShiroAuthToken( AuthToken.newBasicAuthToken( USERNAME, PASSWORD, null ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME, AuthToken.REALM_KEY, null ) ) ); testTokenSupportsRealm( token, true, "unknown", "native", "ldap" ); } @@ -78,7 +80,7 @@ public void shouldSupportBasicAuthTokenWithWildcardRealm() throws Exception ShiroAuthToken token = new ShiroAuthToken( AuthToken.newBasicAuthToken( USERNAME, PASSWORD, "*" ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME, AuthToken.REALM_KEY, "*" ) ) ); testTokenSupportsRealm( token, true, "unknown", "native", "ldap" ); } @@ -90,7 +92,7 @@ public void shouldSupportBasicAuthTokenWithSpecificRealm() throws Exception ShiroAuthToken token = new ShiroAuthToken( AuthToken.newBasicAuthToken( USERNAME, PASSWORD, realm ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME, AuthToken.REALM_KEY, "ldap" ) ) ); testTokenSupportsRealm( token, true, realm ); testTokenSupportsRealm( token, false, "unknown", "native" ); @@ -104,7 +106,7 @@ public void shouldSupportCustomAuthTokenWithSpecificRealm() throws Exception new ShiroAuthToken( AuthToken.newCustomAuthToken( USERNAME, PASSWORD, realm, AuthToken.BASIC_SCHEME ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME, AuthToken.REALM_KEY, "ldap" ) ) ); testTokenSupportsRealm( token, true, realm ); testTokenSupportsRealm( token, false, "unknown", "native" ); @@ -120,7 +122,7 @@ public void shouldSupportCustomAuthTokenWithSpecificRealmAndParameters() throws AuthToken.newCustomAuthToken( USERNAME, PASSWORD, realm, AuthToken.BASIC_SCHEME, params ) ); testBasicAuthToken( token, USERNAME, PASSWORD, AuthToken.BASIC_SCHEME ); assertThat( "Token map should have only expected values", token.getAuthTokenMap(), - equalTo( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, + authTokenMatcher( map( AuthToken.PRINCIPAL, USERNAME, AuthToken.CREDENTIALS, PASSWORD, AuthToken.SCHEME_KEY, AuthToken.BASIC_SCHEME, AuthToken.REALM_KEY, "ldap", "parameters", params ) ) ); testTokenSupportsRealm( token, true, realm ); @@ -151,6 +153,6 @@ private void testBasicAuthToken( ShiroAuthToken token, String username, String p { assertThat( "Token should have basic scheme", token.getScheme(), equalTo( scheme ) ); assertThat( "Token have correct principal", token.getPrincipal(), equalTo( username ) ); - assertThat( "Token have correct credentials", token.getCredentials(), equalTo( password ) ); + assertThat( "Token have correct credentials", token.getCredentials(), equalTo( password( password ) ) ); } } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltInitChangePasswordTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltInitChangePasswordTest.java index 3790dcca455ee..dad7f17d43a25 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltInitChangePasswordTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltInitChangePasswordTest.java @@ -78,7 +78,7 @@ public void shouldLogFailedInitPasswordChange() private Map authToken( String username, String password, String newPassword ) { - return map( "principal", username, "credentials", password, - "new_credentials", newPassword, "scheme", "basic" ); + return map( "principal", username, "credentials", password( password ), + "new_credentials", password( newPassword ), "scheme", "basic" ); } } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/plugin/TestCredentialsOnlyPlugin.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/plugin/TestCredentialsOnlyPlugin.java index 73f2d3b046b71..26c890c59c0a8 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/plugin/TestCredentialsOnlyPlugin.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/plugin/TestCredentialsOnlyPlugin.java @@ -59,7 +59,9 @@ class AuthenticationInfo implements CustomCacheableAuthenticationInfo, CustomCac AuthenticationInfo( String username, char[] credentials ) { this.username = username; - this.credentials = credentials; + // Since the credentials array will be cleared we make need to make a copy here + // (in a real world scenario you would probably not store this copy in clear text) + this.credentials = credentials.clone(); } @Override