@@ -30,6 +30,8 @@ namespace FirebaseAdmin.Auth.Tests
3030{
3131 public class FirebaseTokenVerifierTest : IDisposable
3232 {
33+ private const long ClockSkewSeconds = 5 * 60 ;
34+
3335 private static readonly IPublicKeySource KeySource = new FileSystemPublicKeySource (
3436 "./resources/public_cert.pem" ) ;
3537
@@ -130,25 +132,65 @@ await Assert.ThrowsAsync<FirebaseException>(
130132 [ Fact ]
131133 public async Task Expired ( )
132134 {
135+ var expiryTime = Clock . UnixTimestamp ( ) - ( ClockSkewSeconds + 1 ) ;
133136 var payload = new Dictionary < string , object > ( )
134137 {
135- { "exp" , Clock . UnixTimestamp ( ) - 60 } ,
138+ { "exp" , expiryTime } ,
136139 } ;
137140 var idToken = await CreateTestTokenAsync ( payloadOverrides : payload ) ;
138- await Assert . ThrowsAsync < FirebaseException > (
141+ var exception = await Assert . ThrowsAsync < FirebaseException > (
139142 async ( ) => await TokenVerifier . VerifyTokenAsync ( idToken ) ) ;
143+ var expectedMessage = $ "Firebase ID token expired at { expiryTime } . "
144+ + $ "Expected to be greater than { Clock . UnixTimestamp ( ) } .";
145+ Assert . Equal ( expectedMessage , exception . Message ) ;
146+ }
147+
148+ [ Fact ]
149+ public async Task ExpiryTimeInAcceptableRange ( )
150+ {
151+ var expiryTimeSeconds = Clock . UnixTimestamp ( ) - ClockSkewSeconds ;
152+ var payload = new Dictionary < string , object > ( )
153+ {
154+ { "exp" , expiryTimeSeconds } ,
155+ } ;
156+ var idToken = await CreateTestTokenAsync ( payloadOverrides : payload ) ;
157+
158+ var decoded = await TokenVerifier . VerifyTokenAsync ( idToken ) ;
159+
160+ Assert . Equal ( "testuser" , decoded . Uid ) ;
161+ Assert . Equal ( expiryTimeSeconds , decoded . ExpirationTimeSeconds ) ;
140162 }
141163
142164 [ Fact ]
143165 public async Task InvalidIssuedAt ( )
144166 {
167+ var issuedAt = Clock . UnixTimestamp ( ) + ( ClockSkewSeconds + 1 ) ;
145168 var payload = new Dictionary < string , object > ( )
146169 {
147- { "iat" , Clock . UnixTimestamp ( ) + 60 } ,
170+ { "iat" , issuedAt } ,
148171 } ;
149172 var idToken = await CreateTestTokenAsync ( payloadOverrides : payload ) ;
150- await Assert . ThrowsAsync < FirebaseException > (
173+ var exception = await Assert . ThrowsAsync < FirebaseException > (
151174 async ( ) => await TokenVerifier . VerifyTokenAsync ( idToken ) ) ;
175+ var expectedMessage = $ "Firebase ID token issued at future timestamp { issuedAt } . "
176+ + $ "Expected to be less than { Clock . UnixTimestamp ( ) } .";
177+ Assert . Equal ( expectedMessage , exception . Message ) ;
178+ }
179+
180+ [ Fact ]
181+ public async Task IssuedAtInAcceptableRange ( )
182+ {
183+ var issuedAtSeconds = Clock . UnixTimestamp ( ) + ClockSkewSeconds ;
184+ var payload = new Dictionary < string , object > ( )
185+ {
186+ { "iat" , issuedAtSeconds } ,
187+ } ;
188+ var idToken = await CreateTestTokenAsync ( payloadOverrides : payload ) ;
189+
190+ var decoded = await TokenVerifier . VerifyTokenAsync ( idToken ) ;
191+
192+ Assert . Equal ( "testuser" , decoded . Uid ) ;
193+ Assert . Equal ( issuedAtSeconds , decoded . IssuedAtTimeSeconds ) ;
152194 }
153195
154196 [ Fact ]
0 commit comments