数日前、Webアプリをasp.netコア1.1からコア2.0にアップグレードすることにしました。認証は20〜30分以上持続しないことを除き、小さな変更の後はすべて正常に動作するようです。
Visual Studioからデフォルトの例を使用できます。これは、自分のwebappと"ASP.NET Core Web Application"-> .NET Framework 4.6.1 + ASP.NET Core 2.0 + MVC +で同じ問題が発生するためです。個々のユーザーアカウント。
設定はデフォルトで、14日間ログインしているユーザーである必要があります。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
...
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseAuthentication();
...
}
問題は、ユーザーが20〜30分間しかログインしていないことです。ユーザーがログインすると(「Remember me」が選択されている)、ページ間を移動したり、ブラウザーを再度開いたりしても、ユーザーはログインしたままになります。したがって、認証Cookieが機能しているようです。ただし、20〜30分後にユーザーが自動的にログアウトされるか、Cookieの有効期限が切れると言います(どうなるかわかりません)。再度ログインすると、ゲームが再び開始されます。
アプリケーションCookieの有効期限を設定しようとしましたが、これで問題は解決しません。
services.ConfigureApplicationCookie(options => {
options.ExpireTimeSpan = TimeSpan.FromDays(1); // Just shortens cookie expiration time, but still logs out users after 20-30 minutes.
});
20〜30分かかるため、デフォルトのセッションタイムアウトのように見えます。
services.AddSession(options =>
{
options.Cookie.Expiration = TimeSpan.FromDays(1); // This throws an error "Expiration cannot be set for the cookie defined by SessionOptions"
options.IdleTimeout = TimeSpan.FromDays(1); // This changes session sliding expiration time...
});
同じ実装がASP.NET Core 1.1でも問題なく機能しました。
それでは、これに関してさまざまなフォーラムをスパム送信しました:)そして、ここに私の発見があります。オリジナル https://github.com/aspnet/Identity/issues/1389
これがどのように機能するかについての私の理解には大きなギャップがあったようです。また、私は少し嘘をついていることがわかりました。だから私と同じくらい愚かな他の人のために仕上げる。
_services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<SecurityStampValidatorOptions>(options => options.ValidationInterval = TimeSpan.FromSeconds(10));
services.AddAuthentication()
.Services.ConfigureApplicationCookie(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
});
_
私の理解では、これは次のように機能します。
ユーザーがログに記録されているかどうかの確認は、リクエストの比率に応じて10秒ごとに行われます。サーバーは、サーバーoptions.ValidationInterval = TimeSpan.FromSeconds(10))
へのすべてのリクエストでセキュリティスタンプをチェックします。
cookieは少なくとも30分間有効ですoptions.ExpireTimeSpan = TimeSpan.FromMinutes(30);
ですが、ページが更新またはナビゲートされている場合は、_options.SlidingExpiration = true;
_で拡張できます。
重要!私のように「スマート」になりすぎず、ログイン成功直後に_userManager.UpdateSecurityStampAsync(user);
を実行しないでください。これにより、セキュリティスタンプが更新され、次の検証検証が失敗するためです。
サーバーは、最後の要求の後、限られた時間だけセッションを保持します。セッションタイムアウトを設定するか、デフォルト値の20分を使用できます。
デフォルト値を変更するには、ConfigureServicesメソッドを編集します。
public void ConfigureServices(IServiceCollection services)
{
....
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.CookieName = ".MyApplication";
});
}
このトピックをご覧ください。セッションを長時間ライブで使用するのに役立ちます。
私は専門家ではないので、この投稿でそれが明らかになると確信していますが、IISで古いバージョンのASP.NET(Webフォーム)を実行する前にこの問題が発生しました。
問題は、IISにはサーバー自体に設定されたセッションタイムアウトの独自の設定があり、配置前にサイトで構成したものによって上書きされることはありません。
これは特に、ASP.NET Webフォームにサービスを提供する共有サーバーにとって理にかなっています。クライアントのユーザーが誰がどのくらいの量のセッションデータを蓄積し、無期限に利用可能にしておく必要はありません。
AJAXの呼び出しを使用してセッションを維持することは機能するはずです。