2017-02-01 3 views
5

私はセッションとアイデンティティを実装したAzure WebサイトでホストされているASP.NET Core MVCアプリケーションを持っています。私の問題は、30分後にログアウトすることです。私が過去30分間に活動しているかどうかは関係ありません。ASP.NET Core Webサイトのタイムアウトが30分後

検索しているうちに、問題がSecurityStampのものであることが判明しました。found hereです。私は、次の手順を実行して、これを実装しようとしました:

ここでセキュリティスタンプのものと私のUserManager impelmentationです:

public class UserManager : UserManager<Login> 
{ 
    public UserManager(
     IUserStore<Login> store, 
     IOptions<IdentityOptions> optionsAccessor, 
     IPasswordHasher<Login> passwordHasher, 
     IEnumerable<IUserValidator<Login>> userValidators, 
     IEnumerable<IPasswordValidator<Login>> passwordValidators, 
     ILookupNormalizer keyNormalizer, 
     IdentityErrorDescriber errors, 
     IServiceProvider services, 
     ILogger<UserManager<Login>> logger) 
     : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) 
    { 
     // noop 
    } 

    public override bool SupportsUserSecurityStamp => true; 

    public override async Task<string> GetSecurityStampAsync(Login login) 
    { 
     return await Task.FromResult("MyToken"); 
    } 

    public override async Task<IdentityResult> UpdateSecurityStampAsync(Login login) 
    { 
     return await Task.FromResult(IdentityResult.Success); 
    } 
} 

ここStartup.csに私ConfigureServices方法です:

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddApplicationInsightsTelemetry(Configuration); 

    services.AddSingleton(_ => Configuration); 

    services.AddSingleton<IUserStore<Login>, UserStore>(); 
    services.AddSingleton<IRoleStore<Role>, RoleStore>(); 

    services.AddIdentity<Login, Role>(o => 
    { 
     o.Password.RequireDigit = false; 
     o.Password.RequireLowercase = false; 
     o.Password.RequireUppercase = false; 
     o.Password.RequiredLength = 6; 
     o.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(365); 
     o.Cookies.ApplicationCookie.SlidingExpiration = true; 
     o.Cookies.ApplicationCookie.AutomaticAuthenticate = true; 
    }) 
     .AddUserStore<UserStore>() 
     .AddUserManager<UserManager>() 
     .AddRoleStore<RoleStore>() 
     .AddRoleManager<RoleManager>() 
     .AddDefaultTokenProviders(); 

    services.AddScoped<SignInManager<Login>, SignInManager<Login>>(); 
    services.AddScoped<UserManager<Login>, UserManager<Login>>(); 

    services.Configure<AuthorizationOptions>(options => 
    { 
     options.AddPolicy("Admin", policy => policy.Requirements.Add(new AdminRoleRequirement(new RoleRepo(Configuration)))); 
     options.AddPolicy("SuperUser", policy => policy.Requirements.Add(new SuperUserRoleRequirement(new RoleRepo(Configuration)))); 
     options.AddPolicy("DataIntegrity", policy => policy.Requirements.Add(new DataIntegrityRoleRequirement(new RoleRepo(Configuration)))); 
    }); 

    services.Configure<FormOptions>(x => x.ValueCountLimit = 4096); 
    services.AddScoped<IPasswordHasher<Login>, PasswordHasher>(); 

    services.AddDistributedMemoryCache(); 
    services.AddSession(); 

    services.AddMvc(); 

    // repos 
    InjectRepos(services); 

    // services 
    InjectServices(services); 
} 

そして最後にここにStartup.csのConfigureメソッドがあります:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

    app.UseApplicationInsightsRequestTelemetry(); 

    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseDatabaseErrorPage(); 
     app.UseBrowserLink(); 
    } 
    else 
    { 
     app.UseExceptionHandler("/home/error"); 
    } 

    app.UseStatusCodePages(); 

    app.UseStaticFiles(); 

    app.UseSession(); 
    app.UseIdentity(); 

    app.UseMiddleware(typeof (ErrorHandlingMiddleware)); 
    app.UseMiddleware(typeof (RequestLogMiddleware)); 

    app.UseMvc(routes => 
    { 
     routes.MapRoute(
      name: "default", 
      template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 

W帽子が私の実装に間違っていますか?

アップデート::私のUserManagerがセキュリティスタンプのためのインターフェースから継承していないことに気付きました。何が必要なのでしょうか?

答えて

1

あなたはIISでホストされていますか?その場合は、コードに何も問題はないかもしれませんが、アプリケーションプールがリサイクルされる可能性があります(アプリケーションプールの詳細設定を確認してください)。それが起こると、あなたのバイナリはメモリからアンロードされ、新しいものに置き換えられます、そのPIDは変化しますか?

+0

申し訳ありませんが、これはAzureでホストされているため、IISを制御できるとは思われません。 – ganders

3

これは単にenable and configure Data Protectionが必要なためです。 Cookieとセッションの設定が正しいように見えます。アプリケーションがリサイクルされたり、サーバーが別のサーバーに負荷分散したり、新しい展開が行われたりすると、新しいデータ保護キーがメモリに作成されるため、ユーザーのセッションキーは無効になります。だから、すべてを行う必要があるStartup.csに以下を追加します:

services.AddDataProtection() 
     .PersistKeysToFileSystem(new DirectoryInfo(@"D:\writable\temp\directory\")) 
     .SetDefaultKeyLifetime(TimeSpan.FromDays(14)); 

は、これを適切に設定し、データ保護キー(ファイルシステム、Redisのを保存する場所の異なるオプションする方法については、マニュアルを参照して使用します、レジストリなど)。あなたはasp.netのweb.configのマシンキーの代わりにデータ保護キーを考えることができます。

Azureを使用していると述べたので、このパッケージMicrosoft.AspNetCore.DataProtection.AzureStorageを使用してキーを保存してください。だからあなたはuse this example of how to use Azure Storageでした。

+0

私のアプリケーションプールは30分ごとにリサイクルされ、最後にログインした時間と同期されますか?それは私には意味がありません。 – ganders

+0

これはおそらくリサイクルされていないでしょう。しかしAspNetCoreの文書では、データ保護キーはデフォルトでメモリに生成されていると述べています。このデータ保護キーが有効な場合、ユーザーには有効ではないセッションとIDのCookieデータ(ValidateAntiForgeryTokenアクションフィルタ)変更。 – truemedia

+0

私は[Data Protectionのデフォルト設定](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/default-settings#data-protection-default-settings)に注目しました。 )Azureで実際にあなたを設定するにはかなり良いです。あなたは 'services.AddDataProtection();'というコードを追加することができます。 Azureは自動的にキーを保持します。また、IISを使用する人は、 'PersistKeysToFileSystem'オプションを必要とせずに、単一のマシンでうまく動作します。 – truemedia

関連する問題