Skip to content

Commit f90d2fe

Browse files
committed
Allow dropping tokens from the session manager for easier recovery on lookup failures.
Closes gh-684
1 parent 62ca6ad commit f90d2fe

File tree

4 files changed

+84
-4
lines changed

4 files changed

+84
-4
lines changed

spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.springframework.scheduling.TaskScheduler;
2626
import org.springframework.util.Assert;
2727
import org.springframework.util.ClassUtils;
28-
import org.springframework.util.StringUtils;
2928
import org.springframework.vault.VaultException;
3029
import org.springframework.vault.authentication.event.*;
3130
import org.springframework.vault.client.VaultHttpHeaders;
@@ -149,11 +148,18 @@ protected void setToken(Optional<TokenWrapper> token) {
149148

150149
@Override
151150
public void destroy() {
151+
revoke();
152+
}
152153

153-
Optional<TokenWrapper> token = getToken();
154-
setToken(Optional.empty());
154+
/**
155+
* Revoke and drop the current {@link VaultToken}.
156+
* @since 3.0.2
157+
*/
158+
public void revoke() {
155159

160+
Optional<TokenWrapper> token = getToken();
156161
token.filter(TokenWrapper::isRevocable).map(TokenWrapper::getToken).ifPresent(this::revoke);
162+
setToken(Optional.empty());
157163
}
158164

159165
/**

spring-vault-core/src/main/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManager.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.springframework.scheduling.TaskScheduler;
2727
import org.springframework.util.Assert;
2828
import org.springframework.util.ClassUtils;
29-
import org.springframework.util.StringUtils;
3029
import org.springframework.vault.VaultException;
3130
import org.springframework.vault.authentication.event.*;
3231
import org.springframework.vault.client.VaultHttpHeaders;
@@ -145,6 +144,23 @@ public void destroy() {
145144
revokeNow(tokenMono);
146145
}
147146

147+
/**
148+
* Revoke and drop the current {@link VaultToken}.
149+
* @return a mono emitting completion upon successful revocation.
150+
* @since 3.0.2
151+
*/
152+
public Mono<Void> revoke() {
153+
return doRevoke(this.token.get()).doOnSuccess(unused -> this.token.set(EMPTY));
154+
}
155+
156+
/**
157+
* Revoke and drop the current {@link VaultToken} now.
158+
* @since 3.0.2
159+
*/
160+
public void revokeNow() {
161+
revoke().block(Duration.ofSeconds(5));
162+
}
163+
148164
/**
149165
* Revoke a {@link VaultToken} now and block execution until revocation completes.
150166
* @param tokenMono

spring-vault-core/src/test/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerIntegrationTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,33 @@ public VaultToken getSessionToken() {
9999
sessionManager.renewToken();
100100
}
101101

102+
@Test
103+
void shouldRevokeToken() {
104+
105+
final LoginToken loginToken = createLoginToken();
106+
TokenAuthentication tokenAuthentication = new TokenAuthentication(loginToken);
107+
108+
LifecycleAwareSessionManager sessionManager = new LifecycleAwareSessionManager(tokenAuthentication,
109+
this.taskScheduler, prepare().getRestTemplate());
110+
111+
sessionManager.getSessionToken();
112+
sessionManager.revoke();
113+
114+
prepare().getVaultOperations().doWithSession(restOperations -> {
115+
116+
try {
117+
restOperations.getForEntity("auth/token/lookup/{token}", Map.class, loginToken.toCharArray());
118+
fail("Missing HttpStatusCodeException");
119+
}
120+
catch (HttpStatusCodeException e) {
121+
// Compatibility across Vault versions.
122+
assertThat(e.getStatusCode()).isIn(HttpStatus.BAD_REQUEST, HttpStatus.NOT_FOUND, HttpStatus.FORBIDDEN);
123+
}
124+
125+
return null;
126+
});
127+
}
128+
102129
@Test
103130
void shouldRevokeOnDisposal() {
104131

spring-vault-core/src/test/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManagerIntegrationTests.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323
import java.util.concurrent.TimeUnit;
2424
import java.util.concurrent.atomic.AtomicInteger;
25+
import java.util.concurrent.atomic.AtomicReference;
2526
import java.util.stream.Stream;
2627

2728
import org.assertj.core.util.Files;
@@ -171,6 +172,36 @@ void shouldRevokeOnDisposal() {
171172
});
172173
}
173174

175+
@Test
176+
void shouldRevokeToken() {
177+
178+
LoginToken loginToken = createLoginToken();
179+
180+
ReactiveLifecycleAwareSessionManager sessionManager = new ReactiveLifecycleAwareSessionManager(
181+
() -> Flux.fromStream(Stream.of((VaultToken) loginToken)).next(), this.taskScheduler,
182+
prepare().getWebClient());
183+
184+
sessionManager.getSessionToken() //
185+
.as(StepVerifier::create) //
186+
.expectNext(loginToken) //
187+
.verifyComplete();
188+
sessionManager.revokeNow();
189+
190+
prepare().getVaultOperations().doWithSession(restOperations -> {
191+
192+
try {
193+
restOperations.getForEntity("auth/token/lookup/{token}", Map.class, loginToken.toCharArray());
194+
fail("Missing HttpStatusCodeException");
195+
}
196+
catch (HttpStatusCodeException e) {
197+
// Compatibility across Vault versions.
198+
assertThat(e.getStatusCode()).isIn(HttpStatus.BAD_REQUEST, HttpStatus.NOT_FOUND, HttpStatus.FORBIDDEN);
199+
}
200+
201+
return null;
202+
});
203+
}
204+
174205
private LoginToken createLoginToken() {
175206

176207
VaultTokenOperations tokenOperations = prepare().getVaultOperations().opsForToken();

0 commit comments

Comments
 (0)