我们最近将。net core应用部署到一个负载均衡的生产环境中。用户报告说,网站断断续续地死机——通常是在20到30分钟之后。应用程序不能再从数据库中获取数据,用户被强制重新登录。这似乎最常发生在交通高峰期。
在部署之前,应用程序在负载均衡服务器上进行了测试,一切正常。
查看应用程序的日志,我看到以下消息:
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[7]
Cookies was not authenticated. Failure message: Unprotect ticket failed
我在想可能是数据保护的设置出了问题。它目前使用数据库上下文方案。
中间件是这样的:
public void ConfigureServices(IServiceCollection services)
{
// Add a DbContext to store the Database Keys
services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DataProtection")));
// using Microsoft.AspNetCore.DataProtection;
services.AddDataProtection()
.PersistKeysToDbContext<DatabaseContext>();
services.AddCors(options =>
{
options.AddPolicy("AllowAll",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
services.Configure<EnvironmentSettings>(options => Configuration.GetSection("EnvironmentSettings").Bind(options));
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.Secure = CookieSecurePolicy.SameAsRequest;
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddCookie(cookieOptions =>
{
cookieOptions.AccessDeniedPath = "/AccessDenied";
cookieOptions.ExpireTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(Configuration["wsfed:cookieTimeout"]));
cookieOptions.Cookie.SameSite = SameSiteMode.None;
cookieOptions.Cookie.Name = "FedAuth";
cookieOptions.Cookie.HttpOnly = true;
cookieOptions.Cookie.IsEssential = true;
})
.AddWsFederation(options =>
{
options.Wtrealm = Configuration["wsfed:realm"];
options.MetadataAddress = Configuration["wsfed:metadata"];
options.AllowUnsolicitedLogins = true;
options.CorrelationCookie.SameSite = SameSiteMode.None;
options.Events.OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.Wct = DateTimeOffset.UtcNow.ToString();
return Task.CompletedTask;
};
options.Events.OnSecurityTokenValidated += context =>
{
context.Properties.RedirectUri = Configuration["wsfed:redirecturi"];
return Task.CompletedTask;
};
options.Events.OnRemoteFailure += context =>
{
context.HandleResponse();
if (context.Failure.Message == "Correlation failed.")
{
context.Response.Redirect(Configuration["wsfed:realm"]);
}
return Task.CompletedTask;
};
});
数据库上下文类:
public class DatabaseContext : DbContext, IDataProtectionKeyContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
}
以下是我们迄今为止尝试过的一些事情:
- 检查数据库中的DataProtectionKeys表中的过期密钥。一切看起来都很好。
- IIS: AppPool设置空闲超时为0,启动模式为'Always Running', Preload Enabled = True 在应用程序处于活动状态时关闭负载平衡,试图在暂存中复制问题。没有问题,应用程序保持与数据库的连接并继续工作。
- 清除缓存以删除现有cookie
有什么问题吗?
在我的情况下,问题是我在设置中使用了错误的加密算法。我正在使用cookie认证。
我必须将SHA-1更改为SHA-512,然后服务器才能"取消保护"。(正确解密?)验证cookie