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
|
@Bean
|
||||||
@ConditionalOnMissingBean(Neo4jConnectionDetails.class)
|
@ConditionalOnMissingBean(Neo4jConnectionDetails.class)
|
||||||
PropertiesNeo4jConnectionDetails neo4jConnectionDetails(Neo4jProperties properties) {
|
PropertiesNeo4jConnectionDetails neo4jConnectionDetails(Neo4jProperties properties,
|
||||||
return new PropertiesNeo4jConnectionDetails(properties);
|
ObjectProvider<AuthTokenManager> authTokenManager) {
|
||||||
|
return new PropertiesNeo4jConnectionDetails(properties, authTokenManager.getIfUnique());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public Driver neo4jDriver(Neo4jProperties properties, Environment environment,
|
public Driver neo4jDriver(Neo4jProperties properties, Environment environment,
|
||||||
Neo4jConnectionDetails connectionDetails, ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers,
|
Neo4jConnectionDetails connectionDetails,
|
||||||
ObjectProvider<AuthTokenManager> authTokenManagers) {
|
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers) {
|
||||||
|
|
||||||
Config config = mapDriverConfig(properties, connectionDetails,
|
Config config = mapDriverConfig(properties, connectionDetails,
|
||||||
configBuilderCustomizers.orderedStream().toList());
|
configBuilderCustomizers.orderedStream().toList());
|
||||||
AuthTokenManager authTokenManager = authTokenManagers.getIfUnique();
|
AuthTokenManager authTokenManager = connectionDetails.getAuthTokenManager();
|
||||||
if (authTokenManager != null) {
|
if (authTokenManager != null) {
|
||||||
return GraphDatabase.driver(connectionDetails.getUri(), authTokenManager, config);
|
return GraphDatabase.driver(connectionDetails.getUri(), authTokenManager, config);
|
||||||
}
|
}
|
||||||
|
@ -187,8 +188,11 @@ public class Neo4jAutoConfiguration {
|
||||||
|
|
||||||
private final Neo4jProperties properties;
|
private final Neo4jProperties properties;
|
||||||
|
|
||||||
PropertiesNeo4jConnectionDetails(Neo4jProperties properties) {
|
private final AuthTokenManager authTokenManager;
|
||||||
|
|
||||||
|
PropertiesNeo4jConnectionDetails(Neo4jProperties properties, AuthTokenManager authTokenManager) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
this.authTokenManager = authTokenManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -217,6 +221,11 @@ public class Neo4jAutoConfiguration {
|
||||||
return AuthTokens.none();
|
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 java.net.URI;
|
||||||
|
|
||||||
import org.neo4j.driver.AuthToken;
|
import org.neo4j.driver.AuthToken;
|
||||||
|
import org.neo4j.driver.AuthTokenManager;
|
||||||
import org.neo4j.driver.AuthTokens;
|
import org.neo4j.driver.AuthTokens;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||||
|
@ -49,4 +50,14 @@ public interface Neo4jConnectionDetails extends ConnectionDetails {
|
||||||
return AuthTokens.none();
|
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;
|
package org.springframework.boot.autoconfigure.neo4j;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.neo4j.driver.AuthToken;
|
||||||
import org.neo4j.driver.AuthTokenManager;
|
import org.neo4j.driver.AuthTokenManager;
|
||||||
import org.neo4j.driver.AuthTokenManagers;
|
import org.neo4j.driver.AuthTokenManagers;
|
||||||
import org.neo4j.driver.AuthTokens;
|
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.api.io.TempDir;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.neo4j.driver.AuthTokenManagers;
|
||||||
import org.neo4j.driver.AuthTokens;
|
import org.neo4j.driver.AuthTokens;
|
||||||
import org.neo4j.driver.Config;
|
import org.neo4j.driver.Config;
|
||||||
import org.neo4j.driver.Config.ConfigBuilder;
|
import org.neo4j.driver.Config.ConfigBuilder;
|
||||||
|
@ -143,7 +144,7 @@ class Neo4jAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void uriShouldDefaultToLocalhost() {
|
void uriShouldDefaultToLocalhost() {
|
||||||
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties()).getUri())
|
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties(), null).getUri())
|
||||||
.isEqualTo(URI.create("bolt://localhost:7687"));
|
.isEqualTo(URI.create("bolt://localhost:7687"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,12 +153,12 @@ class Neo4jAutoConfigurationTests {
|
||||||
URI customUri = URI.create("bolt://localhost:4242");
|
URI customUri = URI.create("bolt://localhost:4242");
|
||||||
Neo4jProperties properties = new Neo4jProperties();
|
Neo4jProperties properties = new Neo4jProperties();
|
||||||
properties.setUri(customUri);
|
properties.setUri(customUri);
|
||||||
assertThat(new PropertiesNeo4jConnectionDetails(properties).getUri()).isEqualTo(customUri);
|
assertThat(new PropertiesNeo4jConnectionDetails(properties, null).getUri()).isEqualTo(customUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void authenticationShouldDefaultToNone() {
|
void authenticationShouldDefaultToNone() {
|
||||||
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties()).getAuthToken())
|
assertThat(new PropertiesNeo4jConnectionDetails(new Neo4jProperties(), null).getAuthToken())
|
||||||
.isEqualTo(AuthTokens.none());
|
.isEqualTo(AuthTokens.none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +167,9 @@ class Neo4jAutoConfigurationTests {
|
||||||
Neo4jProperties properties = new Neo4jProperties();
|
Neo4jProperties properties = new Neo4jProperties();
|
||||||
properties.getAuthentication().setUsername("Farin");
|
properties.getAuthentication().setUsername("Farin");
|
||||||
properties.getAuthentication().setPassword("Urlaub");
|
properties.getAuthentication().setPassword("Urlaub");
|
||||||
assertThat(new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
|
PropertiesNeo4jConnectionDetails connectionDetails = new PropertiesNeo4jConnectionDetails(properties, null);
|
||||||
.isEqualTo(AuthTokens.basic("Farin", "Urlaub"));
|
assertThat(connectionDetails.getAuthToken()).isEqualTo(AuthTokens.basic("Farin", "Urlaub"));
|
||||||
|
assertThat(connectionDetails.getAuthTokenManager()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -177,8 +179,22 @@ class Neo4jAutoConfigurationTests {
|
||||||
authentication.setUsername("Farin");
|
authentication.setUsername("Farin");
|
||||||
authentication.setPassword("Urlaub");
|
authentication.setPassword("Urlaub");
|
||||||
authentication.setRealm("Test Realm");
|
authentication.setRealm("Test Realm");
|
||||||
assertThat(new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
|
PropertiesNeo4jConnectionDetails connectionDetails = new PropertiesNeo4jConnectionDetails(properties, null);
|
||||||
.isEqualTo(AuthTokens.basic("Farin", "Urlaub", "Test Realm"));
|
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
|
@Test
|
||||||
|
@ -186,7 +202,7 @@ class Neo4jAutoConfigurationTests {
|
||||||
Neo4jProperties properties = new Neo4jProperties();
|
Neo4jProperties properties = new Neo4jProperties();
|
||||||
Authentication authentication = properties.getAuthentication();
|
Authentication authentication = properties.getAuthentication();
|
||||||
authentication.setKerberosTicket("AABBCCDDEE");
|
authentication.setKerberosTicket("AABBCCDDEE");
|
||||||
assertThat(new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
|
assertThat(new PropertiesNeo4jConnectionDetails(properties, null).getAuthToken())
|
||||||
.isEqualTo(AuthTokens.kerberos("AABBCCDDEE"));
|
.isEqualTo(AuthTokens.kerberos("AABBCCDDEE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +213,7 @@ class Neo4jAutoConfigurationTests {
|
||||||
authentication.setUsername("Farin");
|
authentication.setUsername("Farin");
|
||||||
authentication.setKerberosTicket("AABBCCDDEE");
|
authentication.setKerberosTicket("AABBCCDDEE");
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(() -> new PropertiesNeo4jConnectionDetails(properties).getAuthToken())
|
.isThrownBy(() -> new PropertiesNeo4jConnectionDetails(properties, null).getAuthToken())
|
||||||
.withMessage("Cannot specify both username ('Farin') and kerberos ticket ('AABBCCDDEE')");
|
.withMessage("Cannot specify both username ('Farin') and kerberos ticket ('AABBCCDDEE')");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +329,7 @@ class Neo4jAutoConfigurationTests {
|
||||||
|
|
||||||
private Config mapDriverConfig(Neo4jProperties properties, ConfigBuilderCustomizer... customizers) {
|
private Config mapDriverConfig(Neo4jProperties properties, ConfigBuilderCustomizer... customizers) {
|
||||||
return new Neo4jAutoConfiguration().mapDriverConfig(properties,
|
return new Neo4jAutoConfiguration().mapDriverConfig(properties,
|
||||||
new PropertiesNeo4jConnectionDetails(properties), Arrays.asList(customizers));
|
new PropertiesNeo4jConnectionDetails(properties, null), Arrays.asList(customizers));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue