Skip to content

Commit

Permalink
Consume authentication events in SecretLeaseContainer.
Browse files Browse the repository at this point in the history
SecretLeaseContainer now listens to authentication events to restart secrets on login token expiry.

Closes gh-698
  • Loading branch information
mp911de committed Sep 21, 2023
1 parent fcf00b5 commit 4a09bea
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,19 @@ public PropertySourceLocator vaultPropertySourceLocator(VaultOperations operatio
/**
* @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
*/
@Bean
@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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,9 @@ private void registerSecretLeaseContainer(ConfigurableBootstrapContext bootstrap
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;
Expand Down Expand Up @@ -181,12 +182,17 @@ SessionManager createSessionManager(ClientAuthentication clientAuthentication,
}

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
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;
Expand Down Expand Up @@ -139,7 +144,9 @@ private VaultTokenSupplier createAuthenticationStepsOperator(AuthenticationSteps
}

SessionManager createSessionManager(ReactiveSessionManager sessionManager) {
return new ReactiveSessionManagerAdapter(sessionManager);
return sessionManager instanceof AuthenticationEventMulticaster
? new ReactiveMulticastingSessionManagerAdapter(sessionManager)
: new ReactiveSessionManagerAdapter(sessionManager);
}

ReactiveSessionManager createReactiveSessionManager(VaultTokenSupplier vaultTokenSupplier,
Expand All @@ -158,11 +165,12 @@ ReactiveSessionManager createReactiveSessionManager(VaultTokenSupplier vaultToke
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;
}

Expand All @@ -175,4 +183,47 @@ public VaultToken getSessionToken() {

}

@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);
}

}

}
2 changes: 1 addition & 1 deletion spring-cloud-vault-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit 4a09bea

Please sign in to comment.