Skip to content

Commit 83a343a

Browse files
committed
Use an atomic write for storing/updating the token
1 parent 64e9344 commit 83a343a

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

services/signin/src/main/java/software/amazon/awssdk/services/signin/auth/LoginCredentialsProvider.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ private RefreshResult<AwsCredentials> updateSigninCredentials() {
138138
() -> SdkClientException.create("Invalid token expiration time. You must re-authenticate.")
139139
);
140140

141-
if (isWithinRefreshWindow(currentExpirationTime, staleTime)
142-
&& isWithinRefreshWindow(currentExpirationTime, prefetchTime)) {
141+
if (shouldRefresh(currentExpirationTime, staleTime)
142+
&& shouldRefresh(currentExpirationTime, prefetchTime)) {
143143
log.debug(() -> "Using access token from disk, current expiration time is : " + currentExpirationTime);
144144
AwsCredentials credentials = tokenFromDisc.getAccessToken()
145145
.toBuilder()
@@ -238,9 +238,14 @@ public Builder toBuilder() {
238238
return new BuilderImpl(this);
239239
}
240240

241-
private static boolean isWithinRefreshWindow(Instant expiration, Duration staleTime) {
241+
242+
/**
243+
*
244+
* @return true if the token should be refreshed (it is after the given refresh window, eg stale time or prefetch time)
245+
*/
246+
private static boolean shouldRefresh(Instant expiration, Duration refreshWindow) {
242247
Instant now = Instant.now();
243-
return expiration.isAfter(now.plus(staleTime));
248+
return expiration.isAfter(now.plus(refreshWindow));
244249
}
245250

246251
/**

services/signin/src/main/java/software/amazon/awssdk/services/signin/internal/OnDiskTokenManager.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.nio.charset.StandardCharsets;
2323
import java.nio.file.Files;
2424
import java.nio.file.Path;
25+
import java.nio.file.StandardCopyOption;
2526
import java.security.MessageDigest;
2627
import java.security.NoSuchAlgorithmException;
2728
import java.time.Instant;
@@ -81,8 +82,13 @@ public Optional<LoginAccessToken> loadToken() {
8182

8283
@Override
8384
public void storeToken(LoginAccessToken token) {
84-
try (OutputStream os = Files.newOutputStream(tokenLocation)) {
85-
os.write(marshalToken(token));
85+
// atomic write (write to a temp file and then move/replace the destination location).
86+
try {
87+
Path temp = Files.createTempFile(tokenLocation.getParent(), "token-", ".tmp");
88+
try (OutputStream os = Files.newOutputStream(temp)) {
89+
os.write(marshalToken(token));
90+
}
91+
Files.move(temp, tokenLocation, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
8692
} catch (IOException | UncheckedIOException e) {
8793
throw SdkClientException.create("Unable to write token to location " + tokenLocation, e);
8894
}

0 commit comments

Comments
 (0)