Я пытаюсь создать RevalidatingServerAuthenticationStateProvider, чтобы проверить, истек ли срок действия ClaimsPrincipal.
Я создал его реализацию (TokenExpiryAuthStateProvider) и зарегистрировал ее в ConfigureServices, но конструктор никогда не вызывается, как и ValidateAuthenticationStateAsync. (Я также пробовал регистрировать его на фабрике реализации, результат тот же)
Я ввел AuthStateProvider в MainLayout, чтобы увидеть, что было введено, и он все еще вводит ServerAuthenticationStateProvider. Что я делаю не так?
Моя реализация, которая никогда не вызывается:
public class TokenExpiryAuthStateProvider : RevalidatingServerAuthenticationStateProvider
{
protected override TimeSpan RevalidationInterval => TimeSpan.FromSeconds(10);
public TokenExpiryAuthStateProvider(ILoggerFactory logger) : base(logger)
{
}
protected override Task<bool> ValidateAuthenticationStateAsync(AuthenticationState authenticationState, CancellationToken cancellationToken)
{
DateTime expiry = authenticationState.User.GetExpiryDate();
if (expiry < DateTime.UtcNow)
return Task.FromResult(false);
else
return Task.FromResult(true);
}
}
Настроить службы
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<HttpClientFactory>();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = true;
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
services.AddScoped<AuthenticationStateProvider, TokenExpiryAuthStateProvider>();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
services.AddCsla().WithBlazorServerSupport();
}
Внедренный объект:
ОБНОВЛЕНИЕ: должен был упомянуть об этом раньше ... В настоящее время я работаю над серверным проектом, но макеты находятся в общей библиотеке пользовательского интерфейса. Поэтому предложение, сделанное @enet, не подходит, поскольку RevalidatingServerAuthenticationStateProvider не будет доступен в общем проекте, и поэтому TokenExpiryAuthStateProvider находится только в серверном проекте.
Тем не менее, следуя предложению enet, я объявил интерфейс и обновил ConfigureServices, чтобы я мог вставить его в свой общий макет, чтобы опробовать его:
services.AddScoped<TokenExpiryAuthStateProvider>();
services.AddScoped<ITokenExpiryProvider>(provider =>
provider.GetRequiredService<TokenExpiryAuthStateProvider>());
Затем я ввел ITokenExpiryProvider в MainLayout и подписался на событие AuthenticationStateChanged (единственное событие, которое я мог видеть). После интервала обновления состояние не было изменено, и ValidateAuthenticationStateAsync не был вызван. Как начать процесс повторной проверки и почему AddScoped ‹AuthenticationStateProvider, TokenExpiryAuthStateProvider› не работает?
Я думаю, что для моего простого варианта использования будет проще создать класс таймера, который вводится с помощью AuthenticationStateProvider; затем этот класс инкапсулирует периодическую проверку состояния аутентификации и, в свою очередь, вызывает событие, когда сеанс истекает. (Вот как я ожидал, что RevalidatingServerAuthenticationStateProvider будет работать, проверяя ValidateAuthenticationStateAsync по истечении RefreshInterval)
Я все еще хотел бы знать, почему моя реализация не работает и почему ValidateAuthenticationStateAsync никогда не вызывается; Должно быть, я как-то неправильно регистрирую сервис.