@@ -45,6 +45,7 @@ public class OidcIdTokenValidatorTests {
45
45
private Map <String , Object > claims = new HashMap <>();
46
46
private Instant issuedAt = Instant .now ();
47
47
private Instant expiresAt = this .issuedAt .plusSeconds (3600 );
48
+ private Duration clockSkew = Duration .ofSeconds (60 );
48
49
49
50
@ Before
50
51
public void setup () {
@@ -55,12 +56,12 @@ public void setup() {
55
56
}
56
57
57
58
@ Test
58
- public void validateIdTokenWhenValidThenNoErrors () {
59
+ public void validateWhenValidThenNoErrors () {
59
60
assertThat (this .validateIdToken ()).isEmpty ();
60
61
}
61
62
62
63
@ Test
63
- public void validateIdTokenWhenIssuerNullThenHasErrors () {
64
+ public void validateWhenIssuerNullThenHasErrors () {
64
65
this .claims .remove (IdTokenClaimNames .ISS );
65
66
assertThat (this .validateIdToken ())
66
67
.hasSize (1 )
@@ -69,7 +70,7 @@ public void validateIdTokenWhenIssuerNullThenHasErrors() {
69
70
}
70
71
71
72
@ Test
72
- public void validateIdTokenWhenSubNullThenHasErrors () {
73
+ public void validateWhenSubNullThenHasErrors () {
73
74
this .claims .remove (IdTokenClaimNames .SUB );
74
75
assertThat (this .validateIdToken ())
75
76
.hasSize (1 )
@@ -78,7 +79,7 @@ public void validateIdTokenWhenSubNullThenHasErrors() {
78
79
}
79
80
80
81
@ Test
81
- public void validateIdTokenWhenAudNullThenHasErrors () {
82
+ public void validateWhenAudNullThenHasErrors () {
82
83
this .claims .remove (IdTokenClaimNames .AUD );
83
84
assertThat (this .validateIdToken ())
84
85
.hasSize (1 )
@@ -87,7 +88,7 @@ public void validateIdTokenWhenAudNullThenHasErrors() {
87
88
}
88
89
89
90
@ Test
90
- public void validateIdTokenWhenIssuedAtNullThenHasErrors () {
91
+ public void validateWhenIssuedAtNullThenHasErrors () {
91
92
this .issuedAt = null ;
92
93
assertThat (this .validateIdToken ())
93
94
.hasSize (1 )
@@ -96,7 +97,7 @@ public void validateIdTokenWhenIssuedAtNullThenHasErrors() {
96
97
}
97
98
98
99
@ Test
99
- public void validateIdTokenWhenExpiresAtNullThenHasErrors () {
100
+ public void validateWhenExpiresAtNullThenHasErrors () {
100
101
this .expiresAt = null ;
101
102
assertThat (this .validateIdToken ())
102
103
.hasSize (1 )
@@ -105,7 +106,7 @@ public void validateIdTokenWhenExpiresAtNullThenHasErrors() {
105
106
}
106
107
107
108
@ Test
108
- public void validateIdTokenWhenAudMultipleAndAzpNullThenHasErrors () {
109
+ public void validateWhenAudMultipleAndAzpNullThenHasErrors () {
109
110
this .claims .put (IdTokenClaimNames .AUD , Arrays .asList ("client-id" , "other" ));
110
111
assertThat (this .validateIdToken ())
111
112
.hasSize (1 )
@@ -114,7 +115,7 @@ public void validateIdTokenWhenAudMultipleAndAzpNullThenHasErrors() {
114
115
}
115
116
116
117
@ Test
117
- public void validateIdTokenWhenAzpNotClientIdThenHasErrors () {
118
+ public void validateWhenAzpNotClientIdThenHasErrors () {
118
119
this .claims .put (IdTokenClaimNames .AZP , "other" );
119
120
assertThat (this .validateIdToken ())
120
121
.hasSize (1 )
@@ -123,14 +124,14 @@ public void validateIdTokenWhenAzpNotClientIdThenHasErrors() {
123
124
}
124
125
125
126
@ Test
126
- public void validateIdTokenWhenMultipleAudAzpClientIdThenNoErrors () {
127
+ public void validateWhenMultipleAudAzpClientIdThenNoErrors () {
127
128
this .claims .put (IdTokenClaimNames .AUD , Arrays .asList ("client-id" , "other" ));
128
129
this .claims .put (IdTokenClaimNames .AZP , "client-id" );
129
130
assertThat (this .validateIdToken ()).isEmpty ();
130
131
}
131
132
132
133
@ Test
133
- public void validateIdTokenWhenMultipleAudAzpNotClientIdThenHasErrors () {
134
+ public void validateWhenMultipleAudAzpNotClientIdThenHasErrors () {
134
135
this .claims .put (IdTokenClaimNames .AUD , Arrays .asList ("client-id-1" , "client-id-2" ));
135
136
this .claims .put (IdTokenClaimNames .AZP , "other-client" );
136
137
assertThat (this .validateIdToken ())
@@ -140,7 +141,7 @@ public void validateIdTokenWhenMultipleAudAzpNotClientIdThenHasErrors() {
140
141
}
141
142
142
143
@ Test
143
- public void validateIdTokenWhenAudNotClientIdThenHasErrors () {
144
+ public void validateWhenAudNotClientIdThenHasErrors () {
144
145
this .claims .put (IdTokenClaimNames .AUD , Collections .singletonList ("other-client" ));
145
146
assertThat (this .validateIdToken ())
146
147
.hasSize (1 )
@@ -149,37 +150,56 @@ public void validateIdTokenWhenAudNotClientIdThenHasErrors() {
149
150
}
150
151
151
152
@ Test
152
- public void validateIdTokenWhenExpiredThenHasErrors () {
153
- this .issuedAt = Instant .now ().minus (Duration .ofMinutes (1 ));
154
- this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (1 ));
153
+ public void validateWhenExpiredAnd60secClockSkewThenNoErrors () {
154
+ this .issuedAt = Instant .now ().minus (Duration .ofSeconds (60 ));
155
+ this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (30 ));
156
+ this .clockSkew = Duration .ofSeconds (60 );
157
+ assertThat (this .validateIdToken ()).isEmpty ();
158
+ }
159
+
160
+ @ Test
161
+ public void validateWhenExpiredAnd0secClockSkewThenHasErrors () {
162
+ this .issuedAt = Instant .now ().minus (Duration .ofSeconds (60 ));
163
+ this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (30 ));
164
+ this .clockSkew = Duration .ofSeconds (0 );
155
165
assertThat (this .validateIdToken ())
156
166
.hasSize (1 )
157
167
.extracting (OAuth2Error ::getDescription )
158
168
.allMatch (msg -> msg .contains (IdTokenClaimNames .EXP ));
159
169
}
160
170
161
171
@ Test
162
- public void validateIdTokenWhenIssuedAtWayInFutureThenHasErrors () {
172
+ public void validateWhenIssuedAt5minAheadAnd5minClockSkewThenNoErrors () {
163
173
this .issuedAt = Instant .now ().plus (Duration .ofMinutes (5 ));
164
- this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (1 ));
174
+ this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (60 ));
175
+ this .clockSkew = Duration .ofMinutes (5 );
176
+ assertThat (this .validateIdToken ()).isEmpty ();
177
+ }
178
+
179
+ @ Test
180
+ public void validateWhenIssuedAt1minAheadAnd0minClockSkewThenHasErrors () {
181
+ this .issuedAt = Instant .now ().plus (Duration .ofMinutes (1 ));
182
+ this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (60 ));
183
+ this .clockSkew = Duration .ofMinutes (0 );
165
184
assertThat (this .validateIdToken ())
166
185
.hasSize (1 )
167
186
.extracting (OAuth2Error ::getDescription )
168
187
.allMatch (msg -> msg .contains (IdTokenClaimNames .IAT ));
169
188
}
170
189
171
190
@ Test
172
- public void validateIdTokenWhenExpiresAtBeforeNowThenHasErrors () {
173
- this .issuedAt = Instant .now ().minusSeconds (10 );
174
- this .expiresAt = Instant .from (this .issuedAt ).plusSeconds (5 );
191
+ public void validateWhenExpiresAtBeforeNowThenHasErrors () {
192
+ this .issuedAt = Instant .now ().minus (Duration .ofSeconds (10 ));
193
+ this .expiresAt = this .issuedAt .plus (Duration .ofSeconds (5 ));
194
+ this .clockSkew = Duration .ofSeconds (0 );
175
195
assertThat (this .validateIdToken ())
176
196
.hasSize (1 )
177
197
.extracting (OAuth2Error ::getDescription )
178
198
.allMatch (msg -> msg .contains (IdTokenClaimNames .EXP ));
179
199
}
180
200
181
201
@ Test
182
- public void validateIdTokenWhenMissingClaimsThenHasErrors () {
202
+ public void validateWhenMissingClaimsThenHasErrors () {
183
203
this .claims .remove (IdTokenClaimNames .SUB );
184
204
this .claims .remove (IdTokenClaimNames .AUD );
185
205
this .issuedAt = null ;
@@ -196,6 +216,7 @@ public void validateIdTokenWhenMissingClaimsThenHasErrors() {
196
216
private Collection <OAuth2Error > validateIdToken () {
197
217
Jwt idToken = new Jwt ("token123" , this .issuedAt , this .expiresAt , this .headers , this .claims );
198
218
OidcIdTokenValidator validator = new OidcIdTokenValidator (this .registration .build ());
219
+ validator .setClockSkew (this .clockSkew );
199
220
return validator .validate (idToken ).getErrors ();
200
221
}
201
222
}
0 commit comments