2017-02-01 3 views
5

У меня есть приложение ASP.NET Core MVC, размещенное на сайтах Azure, где я реализовал Session и Identity. Моя проблема: через 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:

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 , реестр и т. д.). Вы можете вспомнить ключ защиты данных как замену машинного ключа web.config в asp.net.

Поскольку вы упомянули, что используете Azure, вы можете использовать этот пакет Microsoft.AspNetCore.DataProtection.AzureStorage, чтобы сохранить ключ, чтобы он не сохранялся. Таким образом, вы могли бы use this example of how to use Azure Storage.

+0

Итак, мой пул приложений перерабатывается каждые 30 минут и синхронизируется с тем временем, когда я последний раз вошел в систему? Для меня это не имеет смысла. – ganders

+0

Это, вероятно, не перерабатывается, что часто, нет. Но в документации AspNetCore указано, что ключи защиты данных генерируются в памяти по умолчанию - и защищают данные cookie сеанса и идентификатора 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