Consume authentication events in SecretLeaseContainer.

SecretLeaseContainer now listens to authentication events to restart secrets on login token expiry.

Closes gh-698
This commit is contained in:
Mark Paluch
2023-09-21 12:07:49 +02:00
parent fcf00b5066
commit 4a09beaa5a
5 changed files with 70 additions and 9 deletions

View File

@@ -131,7 +131,9 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
/**
* @param vaultOperations the {@link VaultOperations}.
* @param taskSchedulerWrapper the {@link TaskSchedulerWrapper}.
* @return the {@link SessionManager} for Vault session management.
* @param sessionManager the {@link SessionManager} to listen for authentication
* events.
* @return the {@link SecretLeaseContainer} for Vault secret lease management.
* @see SessionManager
* @see LifecycleAwareSessionManager
*/
@@ -139,8 +141,9 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
@Lazy
@ConditionalOnMissingBean
public SecretLeaseContainer secretLeaseContainer(VaultOperations vaultOperations,
TaskSchedulerWrapper taskSchedulerWrapper) {
return this.configuration.createSecretLeaseContainer(vaultOperations, taskSchedulerWrapper::getTaskScheduler);
TaskSchedulerWrapper taskSchedulerWrapper, SessionManager sessionManager) {
return this.configuration.createSecretLeaseContainer(vaultOperations, taskSchedulerWrapper::getTaskScheduler,
sessionManager);
}
}

View File

@@ -252,8 +252,9 @@ public class VaultConfigDataLoader implements ConfigDataLoader<VaultConfigLocati
VaultConfiguration vaultConfiguration) {
registerIfAbsent(bootstrap, "secretLeaseContainer", SecretLeaseContainer.class, ctx -> {
SessionManager sessionManager = ctx.get(SessionManager.class);
SecretLeaseContainer container = vaultConfiguration.createSecretLeaseContainer(ctx.get(VaultTemplate.class),
() -> ctx.get(TaskSchedulerWrapper.class).getTaskScheduler());
() -> ctx.get(TaskSchedulerWrapper.class).getTaskScheduler(), sessionManager);
try {
container.afterPropertiesSet();

View File

@@ -32,6 +32,7 @@ import org.springframework.vault.authentication.LifecycleAwareSessionManager;
import org.springframework.vault.authentication.LifecycleAwareSessionManagerSupport;
import org.springframework.vault.authentication.SessionManager;
import org.springframework.vault.authentication.SimpleSessionManager;
import org.springframework.vault.authentication.event.AuthenticationEventMulticaster;
import org.springframework.vault.client.ClientHttpRequestFactoryFactory;
import org.springframework.vault.client.RestTemplateBuilder;
import org.springframework.vault.client.RestTemplateCustomizer;
@@ -181,12 +182,17 @@ final class VaultConfiguration {
}
SecretLeaseContainer createSecretLeaseContainer(VaultOperations vaultOperations,
Supplier<TaskScheduler> taskSchedulerSupplier) {
Supplier<TaskScheduler> taskSchedulerSupplier, SessionManager sessionManager) {
VaultProperties.ConfigLifecycle lifecycle = this.vaultProperties.getConfig().getLifecycle();
SecretLeaseContainer container = new SecretLeaseContainer(vaultOperations, taskSchedulerSupplier.get());
if (sessionManager instanceof AuthenticationEventMulticaster am) {
am.addAuthenticationListener(container.getAuthenticationListener());
am.addErrorListener(container.getAuthenticationErrorListener());
}
customizeContainer(lifecycle, container);
return container;

View File

@@ -35,6 +35,11 @@ import org.springframework.vault.authentication.ReactiveSessionManager;
import org.springframework.vault.authentication.SessionManager;
import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.authentication.VaultTokenSupplier;
import org.springframework.vault.authentication.event.AuthenticationErrorEvent;
import org.springframework.vault.authentication.event.AuthenticationErrorListener;
import org.springframework.vault.authentication.event.AuthenticationEvent;
import org.springframework.vault.authentication.event.AuthenticationEventMulticaster;
import org.springframework.vault.authentication.event.AuthenticationListener;
import org.springframework.vault.client.ClientHttpConnectorFactory;
import org.springframework.vault.client.ReactiveVaultEndpointProvider;
import org.springframework.vault.client.VaultEndpointProvider;
@@ -139,7 +144,9 @@ final class VaultReactiveConfiguration {
}
SessionManager createSessionManager(ReactiveSessionManager sessionManager) {
return new ReactiveSessionManagerAdapter(sessionManager);
return sessionManager instanceof AuthenticationEventMulticaster
? new ReactiveMulticastingSessionManagerAdapter(sessionManager)
: new ReactiveSessionManagerAdapter(sessionManager);
}
ReactiveSessionManager createReactiveSessionManager(VaultTokenSupplier vaultTokenSupplier,
@@ -158,11 +165,12 @@ final class VaultReactiveConfiguration {
return CachingVaultTokenSupplier.of(vaultTokenSupplier);
}
private static final class ReactiveSessionManagerAdapter implements SessionManager {
@SuppressWarnings("all")
static class ReactiveSessionManagerAdapter implements SessionManager {
private final ReactiveSessionManager sessionManager;
private ReactiveSessionManagerAdapter(ReactiveSessionManager sessionManager) {
ReactiveSessionManagerAdapter(ReactiveSessionManager sessionManager) {
this.sessionManager = sessionManager;
}
@@ -175,4 +183,47 @@ final class VaultReactiveConfiguration {
}
@SuppressWarnings("all")
static class ReactiveMulticastingSessionManagerAdapter extends ReactiveSessionManagerAdapter
implements AuthenticationEventMulticaster {
private final AuthenticationEventMulticaster delegate;
ReactiveMulticastingSessionManagerAdapter(ReactiveSessionManager sessionManager) {
super(sessionManager);
this.delegate = (AuthenticationEventMulticaster) sessionManager;
}
@Override
public void addAuthenticationListener(AuthenticationListener listener) {
this.delegate.addAuthenticationListener(listener);
}
@Override
public void removeAuthenticationListener(AuthenticationListener listener) {
this.delegate.removeAuthenticationListener(listener);
}
@Override
public void addErrorListener(AuthenticationErrorListener listener) {
this.delegate.addErrorListener(listener);
}
@Override
public void removeErrorListener(AuthenticationErrorListener listener) {
this.delegate.removeErrorListener(listener);
}
@Override
public void multicastEvent(AuthenticationEvent event) {
this.delegate.multicastEvent(event);
}
@Override
public void multicastEvent(AuthenticationErrorEvent event) {
this.delegate.multicastEvent(event);
}
}
}

View File

@@ -20,7 +20,7 @@
<description>Spring Cloud Vault Dependencies</description>
<properties>
<spring-vault.version>3.0.2</spring-vault.version>
<spring-vault.version>3.1.0-SNAPSHOT</spring-vault.version>
</properties>
<dependencyManagement>