2017-02-01 24 views
5

我有一個ASP.NET Core MVC應用程序,託管在Azure網站上,我已經實現了會話和身份。我的問題是,30分鐘後,我退出了。如果我在過去的30分鐘內活動過,沒關係。ASP.NET核心網站在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); 
    } 
} 

這裏是我的ConfigureServices上Startup.cs方法:

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文檔提到,數據保護密鑰默認在內存中生成,並保護會話和身份cookie數據(以及ValidateAntiForgeryToken操作過濾器),如果此數據保護密鑰不會對用戶有效變化。 – truemedia

+0

我剛剛注意到[數據保護的默認設置](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