Polish "Add support for using an AuthTokenManager with Neo4j"

See gh-36650
pull/36693/head
Andy Wilkinson 1 year ago
parent 1f0a3901b2
commit 77e382ec64

@ -64,19 +64,20 @@ public class Neo4jAutoConfiguration {
@Bean
@ConditionalOnMissingBean(Neo4jConnectionDetails.class)
PropertiesNeo4jConnectionDetails neo4jConnectionDetails(Neo4jProperties properties) {
return new PropertiesNeo4jConnectionDetails(properties);
PropertiesNeo4jConnectionDetails neo4jConnectionDetails(Neo4jProperties properties,
ObjectProvider<AuthTokenManager> authTokenManager) {
return new PropertiesNeo4jConnectionDetails(properties, authTokenManager.getIfUnique());
}
@Bean
@ConditionalOnMissingBean
public Driver neo4jDriver(Neo4jProperties properties, Environment environment,
Neo4jConnectionDetails connectionDetails, ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers,
ObjectProvider<AuthTokenManager> authTokenManagers) {
Neo4jConnectionDetails connectionDetails,
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers) {
Config config = mapDriverConfig(properties, connectionDetails,
configBuilderCustomizers.orderedStream().toList());
AuthTokenManager authTokenManager = authTokenManagers.getIfUnique();
AuthTokenManager authTokenManager = connectionDetails.getAuthTokenManager();
if (authTokenManager != null) {
return GraphDatabase.driver(connectionDetails.getUri(), authTokenManager, config);
}
@ -187,8 +188,11 @@ public class Neo4jAutoConfiguration {
private final Neo4jProperties properties;
PropertiesNeo4jConnectionDetails(Neo4jProperties properties) {
private final AuthTokenManager authTokenManager;
PropertiesNeo4jConnectionDetails(Neo4jProperties properties, AuthTokenManager authTokenManager) {
this.properties = properties;
this.authTokenManager = authTokenManager;
}
@Override
@ -217,6 +221,11 @@ public class Neo4jAutoConfiguration {
return AuthTokens.none();
}
@Override
public AuthTokenManager getAuthTokenManager() {
return this.authTokenManager;
}
}
}

@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.neo4j;
import java.net.URI;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.AuthTokenManager;
import org.neo4j.driver.AuthTokens;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
@ -49,4 +50,14 @@ public interface Neo4jConnectionDetails extends ConnectionDetails {
return AuthTokens.none();
}
/**
* Returns the {@link AuthTokenManager} to use for authentication. Defaults to
* {@code null} in which case the {@link #getAuthToken() auth token} should be used.
* @return the auth token manager
* @since 3.2.0
*/
default AuthTokenManager getAuthTokenManager() {
return null;
}
}

@ -16,10 +16,12 @@
package org.springframework.boot.autoconfigure.neo4j;
import java.net.URI;
import java.time.Duration;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.AuthTokenManager;
import org.neo4j.driver.AuthTokenManagers;
import org.neo4j.driver.AuthTokens;
@ -124,4 +126,58 @@ class Neo4jAutoConfigurationIntegrationTests {
}
@SpringBootTest
@Nested
class DriverWithCustomConnectionDetailsIgnoresAuthTokenManager {
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4jServer::getBoltUrl);
registry.add("spring.neo4j.authentication.username", () -> "wrong");
registry.add("spring.neo4j.authentication.password", () -> "alsowrong");
}
@Autowired
private Driver driver;
@Test
void driverCanHandleRequest() {
try (Session session = this.driver.session(); Transaction tx = session.beginTransaction()) {
Result statementResult = tx.run("MATCH (n:Thing) RETURN n LIMIT 1");
assertThat(statementResult.hasNext()).isFalse();
tx.commit();
}
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(Neo4jAutoConfiguration.class)
static class TestConfiguration {
@Bean
AuthTokenManager authTokenManager() {
return AuthTokenManagers.expirationBased(() -> AuthTokens.basic("wrongagain", "stillwrong")
.expiringAt(System.currentTimeMillis() + 5_000));
}
@Bean
Neo4jConnectionDetails connectionDetails() {
return new Neo4jConnectionDetails() {
@Override
public URI getUri() {
return URI.create(neo4jServer.getBoltUrl());
}
@Override
public AuthToken getAuthToken() {
return AuthTokens.basic("neo4j", neo4jServer.getAdminPassword());
}
};
}
}
}
}

@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.neo4j.driver.AuthTokenManagers;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Config;
import org.neo4j.driver.Config.ConfigBuilder;
@ -143,7 +144,7 @@ class Neo4jAutoConfigurationTests {
@Test
void uriShouldDefaultToLocalhost() {
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties()).getUri())
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties(), null).getUri())
.isEqualTo(URI.create("bolt://localhost:7687"));
}
@ -152,12 +153,12 @@ class Neo4jAutoConfigurationTests {
URI customUri = URI.create("bolt://localhost:4242");
Neo4jProperties properties = new Neo4jProperties();
properties.setUri(customUri);
assertThat(new PropertiesNeo4jConnectionDetails(properties).getUri()).isEqualTo(customUri);
assertThat(new PropertiesNeo4jConnectionDetails(properties, null).getUri()).isEqualTo(customUri);
}
@Test
void authenticationShouldDefaultToNone() {
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties()).getAuthToken())
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties(), null).getAuthToken())
.isEqualTo(AuthTokens.none());
}
@ -166,8 +167,9 @@ class Neo4jAutoConfigurationTests {
Neo4jProperties properties = new Neo4jProperties();
properties.getAuthentication().setUsername("Farin");
properties.getAuthentication().setPassword("Urlaub");
assertThat(new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
.isEqualTo(AuthTokens.basic("Farin", "Urlaub"));
PropertiesNeo4jConnectionDetails connectionDetails = new PropertiesNeo4jConnectionDetails(properties, null);
assertThat(connectionDetails.getAuthToken()).isEqualTo(AuthTokens.basic("Farin", "Urlaub"));
assertThat(connectionDetails.getAuthTokenManager()).isNull();
}
@Test
@ -177,8 +179,22 @@ class Neo4jAutoConfigurationTests {
authentication.setUsername("Farin");
authentication.setPassword("Urlaub");
authentication.setRealm("Test Realm");
assertThat(new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
.isEqualTo(AuthTokens.basic("Farin", "Urlaub", "Test Realm"));
PropertiesNeo4jConnectionDetails connectionDetails = new PropertiesNeo4jConnectionDetails(properties, null);
assertThat(connectionDetails.getAuthToken()).isEqualTo(AuthTokens.basic("Farin", "Urlaub", "Test Realm"));
assertThat(connectionDetails.getAuthTokenManager()).isNull();
}
@Test
void authenticationWithAuthTokenManagerAndUsernameShouldProvideAuthTokenManger() {
Neo4jProperties properties = new Neo4jProperties();
Authentication authentication = properties.getAuthentication();
authentication.setUsername("Farin");
authentication.setPassword("Urlaub");
authentication.setRealm("Test Realm");
assertThat(new PropertiesNeo4jConnectionDetails(properties,
AuthTokenManagers.expirationBased(
() -> AuthTokens.basic("username", "password").expiringAt(System.currentTimeMillis() + 5000)))
.getAuthTokenManager()).isNotNull();
}
@Test
@ -186,7 +202,7 @@ class Neo4jAutoConfigurationTests {
Neo4jProperties properties = new Neo4jProperties();
Authentication authentication = properties.getAuthentication();
authentication.setKerberosTicket("AABBCCDDEE");
assertThat(new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
assertThat(new PropertiesNeo4jConnectionDetails(properties, null).getAuthToken())
.isEqualTo(AuthTokens.kerberos("AABBCCDDEE"));
}
@ -197,7 +213,7 @@ class Neo4jAutoConfigurationTests {
authentication.setUsername("Farin");
authentication.setKerberosTicket("AABBCCDDEE");
assertThatIllegalStateException()
.isThrownBy(() -> new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
.isThrownBy(() -> new PropertiesNeo4jConnectionDetails(properties, null).getAuthToken())
.withMessage("Cannot specify both username ('Farin') and kerberos ticket ('AABBCCDDEE')");
}
@ -313,7 +329,7 @@ class Neo4jAutoConfigurationTests {
private Config mapDriverConfig(Neo4jProperties properties, ConfigBuilderCustomizer... customizers) {
return new Neo4jAutoConfiguration().mapDriverConfig(properties,
new PropertiesNeo4jConnectionDetails(properties), Arrays.asList(customizers));
new PropertiesNeo4jConnectionDetails(properties, null), Arrays.asList(customizers));
}
}

Loading…
Cancel
Save