ОБНОВЛЕНИЕ: Похоже, что следующий код не работает:
services.AddDataProtection()
.SetApplicationName(appname)
.PersistKeysToRedis(redis, "DataProtectionKeys")
.ProtectKeysWithCertificate(LoadCert(Configuration));
Невозможно прочитать сертификат из файла pfx.
ОБНОВЛЕНИЕ2: О боже!Файл сертификата был исключен .gitignore! :)) Live & Learn.По крайней мере, мы жили, не так ли?Когда я пытаюсь войти в приложение со страницы входа.Я получаю InvalidOperationException с этим обоснованием:
Не указана схема authenticationScheme, и не найдено DefaultChallengeScheme.
Но когда я снова нажимаю тот же URL, он фактически переходит ксоответствующая страница и работает некоторое время, затем снова выдает то же исключение со статусом HTTP 500 и после 2-й попытки открыть ту же страницу, это успешно.Интересно, что Chrome не так надежен, как IE: если IE не удается восстановить после исключения, Chrome всегда возвращает 404 при последующем представлении страницы, которая вызвала вышеупомянутое исключение.
Поэтому я был бы признателен, если бы кто-тобыть в состоянии предоставить мне идеи, как исправить ситуацию. Очевидно, что проблема связана с аутентификацией, но я не мог понять, что именно должно быть сделано.
Вот соответствующий пример из ConfigureServices () вStartup.cs:
string appname = "MyApp";
var redis = ConnectionMultiplexer.Connect(Configuration.GetConnectionString("RedisConnection"));
services.AddDataProtection()
.SetApplicationName(appname)
.PersistKeysToRedis(redis, "DataProtectionKeys")
.ProtectKeysWithCertificate(LoadCert(Configuration));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthentication( CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.LoginPath = new PathString("/Area/Ctrl/Login");
options.LogoutPath = new PathString("/Area/Ctrl/Logout");
options.Cookie.IsEssential = true;
});
services.AddDistributedRedisCache(o =>
{
o.Configuration = Configuration.GetConnectionString("RedisConnection");
});
services.AddSession(options =>
{
options.Cookie.Name = appname;
options.IdleTimeout = TimeSpan.FromSeconds(600);
});
Вот соответствующий код из Configure () в Startup.cs:
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "areas",
template: "{area:exists}/{controller=Ctrl}/{action=Login}/{id?}"
);
});
Вот как я устанавливаю принципала в контроллере, который обрабатывает вход в систему:
ClaimsIdentity identity = new ClaimsIdentity(GetUserRoleClaims(dbUserData), CookieAuthenticationDefaults.AuthenticationScheme);
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
if (principal == null)
throw new ApplicationException($"Could not create principal for {user?.UserName} user.");
await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
if (httpContext.User == null)
{
httpContext.User = principal;
}