Polish "Add support for using an AuthTokenManager with Neo4j"
See gh-36650
This commit is contained in:
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…
Reference in New Issue