ISystemClock is obsolete
Microsoft.AspNetCore.Authentication.ISystemClock has been used by ASP.NET Core's authentication and identity components since version 1.0 to enable unit testing of time-related functionality, like expiration checking. .NET 8 includes a suitable abstraction, System.TimeProvider, that provides the same functionality and much more. We're taking this opportunity to obsolete ISystemClock and replace it with TimeProvider throughout the ASP.NET Core libraries.
Version introduced
ASP.NET Core 8.0 Preview 5
Previous behavior
ISystemClock was injected into the constructors of the authentication and identity components by dependency injection (DI) and could be overridden for testing.
The default SystemClock implementation truncated to the nearest second for easier formatting.
New behavior
ISystemClock, SystemClock, and the authentication handler constructors that have an ISystemClock parameter have been marked obsolete. Using these APIs in code will generate a warning at compile time.
ISystemClock remains in the dependency injection container but is no longer used. It may be removed from the container in a future version.
TimeProvider is now a settable property on the Options
classes for the authentication and identity components. It can be set directly or by registering a provider in the dependency injection container.
TimeProvider does not truncate to the nearest second. Consumers are expected to correctly format the time as needed.
Type of breaking change
This change affects source compatibility.
Reason for change
This change was made to unify time abstraction across the stack for easier testing.
Recommended action
If you have components that derive from Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions> or Microsoft.AspNetCore.Identity.SecurityStampValidator<TUser>, remove the ISystemClock constructor parameter and call the new base constructor accordingly.
- public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
- : base(options, logger, encoder, clock)
+ public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder)
+ : base(options, logger, encoder)
Similarly, derived implementations that reference the Clock
property on these types should reference the new TimeProvider
property instead.
- var currentUtc = Clock.UtcNow;
+ var currentUtc = TimeProvider.GetUtcNow();
You can set TimeProvider
for testing on the options or via DI.
Affected APIs
- Microsoft.AspNetCore.Authentication.ISystemClock
- Microsoft.AspNetCore.Authentication.SystemClock
- Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>
- Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>.Clock
- CookieAuthenticationHandler(IOptionsMonitor<CookieAuthenticationOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- FacebookHandler(IOptionsMonitor<FacebookOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- GoogleHandler(IOptionsMonitor<GoogleOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- JwtBearerHandler(IOptionsMonitor<JwtBearerOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- MicrosoftAccountHandler(IOptionsMonitor<MicrosoftAccountOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- NegotiateHandler(IOptionsMonitor<NegotiateOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- OAuthHandler<TOptions>(IOptionsMonitor<TOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- OpenIdConnectHandler(IOptionsMonitor<OpenIdConnectOptions>, ILoggerFactory, HtmlEncoder, UrlEncoder, ISystemClock)
- Microsoft.AspNetCore.Authentication.PolicySchemeHandler.PolicySchemeHandler(IOptionsMonitor<PolicySchemeOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>
- SignInAuthenticationHandler<TOptions>(IOptionsMonitor<TOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- SignOutAuthenticationHandler<TOptions>(IOptionsMonitor<TOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- TwitterHandler(IOptionsMonitor<TwitterOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- WsFederationHandler(IOptionsMonitor<WsFederationOptions>, ILoggerFactory, UrlEncoder, ISystemClock)
- SecurityStampValidator<TUser>(IOptions<SecurityStampValidatorOptions>, SignInManager<TUser>, ISystemClock, ILoggerFactory)
- Microsoft.AspNetCore.Identity.SecurityStampValidator<TUser>.Clock
- TwoFactorSecurityStampValidator<TUser>(IOptions<SecurityStampValidatorOptions>, SignInManager<TUser>, ISystemClock, ILoggerFactory)