Skip to content

Commit 77e550a

Browse files
committed
Use timezone to instead of any seconds for clock skew.
1 parent 8d11d84 commit 77e550a

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

src/main/java/org/tinystruct/http/security/JWTManager.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import javax.crypto.SecretKey;
88
import java.time.Duration;
99
import java.time.Instant;
10+
import java.time.ZoneId;
11+
import java.time.ZonedDateTime;
1012
import java.util.Base64;
1113
import java.util.Date;
1214

@@ -18,7 +20,8 @@ public class JWTManager {
1820

1921
/**
2022
* Sets the secret key using a plain text string.
21-
* This method allows for a custom secret key to be used instead of the default one.
23+
* This method allows for a custom secret key to be used instead of the default
24+
* one.
2225
*
2326
* @param secret The secret key as a plain text string
2427
*/
@@ -28,7 +31,8 @@ public void withSecret(String secret) {
2831

2932
/**
3033
* Sets the secret key using a base64 encoded string.
31-
* This method allows for a custom secret key to be used instead of the default one.
34+
* This method allows for a custom secret key to be used instead of the default
35+
* one.
3236
*
3337
* @param base64Secret The secret key as a base64 string
3438
*/
@@ -37,20 +41,36 @@ public void withBase64Secret(String base64Secret) {
3741
}
3842

3943
/**
40-
* Sets the clock skew in seconds.
41-
* This method allows for a leeway in the token's expiration time to account for clock differences between machines.
44+
* Sets the timezone and calculates the clock skew in seconds.
45+
* This method allows for a leeway in the token's expiration time to account for
46+
* clock differences between machines.
4247
*
43-
* @param clockSkew The clock skew in seconds
48+
* @param zoneId The timezone ID
4449
*/
45-
public void withClockSkew(long clockSkew) {
46-
this.clockSkew = clockSkew;
50+
public void withTimezone(ZoneId zoneId) {
51+
this.clockSkew = Duration.between(
52+
ZonedDateTime.now(zoneId).toLocalDateTime(),
53+
ZonedDateTime.now(ZoneId.systemDefault()).toLocalDateTime()).getSeconds();
4754
}
4855

4956
/**
50-
* Builds a JWT with the given subject and claims and returns it as a JWS signed compact String.
57+
* Sets the timezone and calculates the clock skew in seconds.
58+
* This method allows for a leeway in the token's expiration time to account for
59+
* clock differences between machines.
5160
*
52-
* @param subject The subject (typically the user identifier)
53-
* @param builder A Builder object containing the claims to be included in the JWT
61+
* @param timezone The timezone string
62+
*/
63+
public void withTimezone(String timezone) {
64+
this.withTimezone(ZoneId.of(timezone));
65+
}
66+
67+
/**
68+
* Builds a JWT with the given subject and claims and returns it as a JWS signed
69+
* compact String.
70+
*
71+
* @param subject The subject (typically the user identifier)
72+
* @param builder A Builder object containing the claims to be included in the
73+
* JWT
5474
* @param validity The validity period of the token in hours
5575
* @return The generated JWT as a compact JWS signed String
5676
*/
@@ -64,7 +84,8 @@ public String createToken(final String subject, final Builder builder, final lon
6484
// Add the claims from the builder to the JWT
6585
builder.forEach(jwtBuilder::claim);
6686

67-
// Sign the JWT with the provided secret key, or the default key if none provided
87+
// Sign the JWT with the provided secret key, or the default key if none
88+
// provided
6889
if (this.base64Key != null)
6990
jwtBuilder.signWith(this.base64Key);
7091
else
@@ -76,7 +97,8 @@ public String createToken(final String subject, final Builder builder, final lon
7697

7798
/**
7899
* Parses the given JWS signed compact JWT, returning the claims.
79-
* If this method returns without throwing an exception, the token can be trusted.
100+
* If this method returns without throwing an exception, the token can be
101+
* trusted.
80102
*
81103
* @param compactToken The JWT to be parsed
82104
* @return The claims contained in the JWT

src/test/java/org/tinystruct/http/security/JWTManagerTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.junit.jupiter.api.Test;
99
import org.tinystruct.data.component.Builder;
1010

11+
import java.time.ZoneId;
12+
1113
import static org.junit.jupiter.api.Assertions.*;
1214

1315
public class JWTManagerTest {
@@ -78,12 +80,13 @@ public void testTokenWithClockSkew() {
7880
e.printStackTrace();
7981
}
8082

81-
// Set clock skew to 60 seconds
82-
jwtManager.withClockSkew(60);
83+
// Set timezone to UTC to ensure there's some clock skew if the system is not in
84+
// UTC
85+
jwtManager.withTimezone(ZoneId.of("UTC"));
8386

8487
// Parsing the token should NOT throw ExpiredJwtException because of clock skew
8588
assertDoesNotThrow(() -> jwtManager.parseToken(token));
86-
89+
8790
Jws<Claims> parsedToken = jwtManager.parseToken(token);
8891
assertEquals(SUBJECT, parsedToken.getPayload().getSubject());
8992
}

0 commit comments

Comments
 (0)