@@ -264,6 +264,53 @@ public async Task OnValidateIdentityDoesNotRejectsWhenNotExpired()
264
264
Assert . NotNull ( context . Principal ) ;
265
265
}
266
266
267
+ [ Fact ]
268
+ public async Task OnValidateIdentityDoesNotExtendExpirationWhenSlidingIsDisabled ( )
269
+ {
270
+ var user = new PocoUser ( "test" ) ;
271
+ var httpContext = new Mock < HttpContext > ( ) ;
272
+ var userManager = MockHelpers . MockUserManager < PocoUser > ( ) ;
273
+ var identityOptions = new Mock < IOptions < IdentityOptions > > ( ) ;
274
+ identityOptions . Setup ( a => a . Value ) . Returns ( new IdentityOptions ( ) ) ;
275
+ var claimsManager = new Mock < IUserClaimsPrincipalFactory < PocoUser > > ( ) ;
276
+ var options = new Mock < IOptions < SecurityStampValidatorOptions > > ( ) ;
277
+ options . Setup ( a => a . Value ) . Returns ( new SecurityStampValidatorOptions { ValidationInterval = TimeSpan . FromMinutes ( 1 ) } ) ;
278
+ var contextAccessor = new Mock < IHttpContextAccessor > ( ) ;
279
+ contextAccessor . Setup ( a => a . HttpContext ) . Returns ( httpContext . Object ) ;
280
+ var signInManager = new Mock < SignInManager < PocoUser > > ( userManager . Object ,
281
+ contextAccessor . Object , claimsManager . Object , identityOptions . Object , null , new Mock < IAuthenticationSchemeProvider > ( ) . Object , new DefaultUserConfirmation < PocoUser > ( ) ) ;
282
+ signInManager . Setup ( s => s . ValidateSecurityStampAsync ( It . IsAny < ClaimsPrincipal > ( ) ) ) . Returns ( Task . FromResult ( user ) ) ;
283
+ signInManager . Setup ( s => s . CreateUserPrincipalAsync ( It . IsAny < PocoUser > ( ) ) ) . Returns ( Task . FromResult ( new ClaimsPrincipal ( new ClaimsIdentity ( "auth" ) ) ) ) ;
284
+ signInManager . Setup ( s => s . SignInAsync ( user , false , null ) ) . Throws ( new Exception ( "Shouldn't be called" ) ) ;
285
+ var services = new ServiceCollection ( ) ;
286
+ services . AddSingleton ( options . Object ) ;
287
+ services . AddSingleton ( signInManager . Object ) ;
288
+ var clock = new SystemClock ( ) ;
289
+ services . AddSingleton < ISecurityStampValidator > ( new SecurityStampValidator < PocoUser > ( options . Object , signInManager . Object , clock , new LoggerFactory ( ) ) ) ;
290
+ httpContext . Setup ( c => c . RequestServices ) . Returns ( services . BuildServiceProvider ( ) ) ;
291
+ var id = new ClaimsIdentity ( IdentityConstants . ApplicationScheme ) ;
292
+ id . AddClaim ( new Claim ( ClaimTypes . NameIdentifier , user . Id ) ) ;
293
+
294
+ var ticket = new AuthenticationTicket ( new ClaimsPrincipal ( id ) ,
295
+ new AuthenticationProperties
296
+ {
297
+ IssuedUtc = clock . UtcNow - TimeSpan . FromDays ( 1 ) ,
298
+ ExpiresUtc = clock . UtcNow + TimeSpan . FromDays ( 1 ) ,
299
+ } ,
300
+ IdentityConstants . ApplicationScheme ) ;
301
+ var context = new CookieValidatePrincipalContext ( httpContext . Object , new AuthenticationSchemeBuilder ( IdentityConstants . ApplicationScheme ) { HandlerType = typeof ( NoopHandler ) } . Build ( ) ,
302
+ new CookieAuthenticationOptions ( ) { SlidingExpiration = false } , ticket ) ;
303
+ Assert . NotNull ( context . Properties ) ;
304
+ Assert . NotNull ( context . Options ) ;
305
+ Assert . NotNull ( context . Principal ) ;
306
+ await SecurityStampValidator . ValidatePrincipalAsync ( context ) ;
307
+
308
+ // Issued is moved forward, expires is not.
309
+ Assert . Equal ( clock . UtcNow , context . Properties . IssuedUtc ) ;
310
+ Assert . Equal ( clock . UtcNow + TimeSpan . FromDays ( 1 ) , context . Properties . ExpiresUtc ) ;
311
+ Assert . NotNull ( context . Principal ) ;
312
+ }
313
+
267
314
private async Task RunRememberClientCookieTest ( bool shouldStampValidate , bool validationSuccess )
268
315
{
269
316
var user = new PocoUser ( "test" ) ;
0 commit comments