ASP.NET Core网站在30分钟后超时

gan*_*ers 7 c# azure asp.net-core-mvc asp.net-core

我有一个ASP.NET核心MVC应用程序,托管在Azure网站上,我已经实现了Session和Identity.我的问题是,30分钟后,我退出了.如果我在过去的30分钟内一直活跃,那也没关系.

做一些搜索,我发现问题是SecurityStamp的东西,在这里找到.我尝试通过执行以下操作来实现此功能:

这是我的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我在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);
}
Run Code Online (Sandbox Code Playgroud)

最后,这是我在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?}");
    });
}
Run Code Online (Sandbox Code Playgroud)

我的实施在这里有什么问题?

更新:什么秒......我注意到我的UserManager没有继承任何安全标记的接口,是什么需要?

tru*_*dia 5

这仅仅是因为您需要启用和配置数据保护。Cookie和会话设置看起来正确。现在,您正在发生的事情是,无论何时回收应用程序或服务器负载平衡到另一台服务器或发生新的部署等,它都会在内存中创建一个新的数据保护密钥,因此用户的会话密钥无效。因此,您需要做的就是将以下内容添加到Startup.cs中:

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

使用文档了解如何正确设置此设置以及保存数据保护密钥的位置(文件系统,redis,注册表等)的不同选项。您可以将数据保护密钥视为asp.net中web.config机器密钥的替代。

既然您提到您正在使用Azure,则可以使用此程序包Microsoft.AspNetCore.DataProtection.AzureStorage保存密钥,使其持久存在。因此,您可以使用此示例说明如何使用Azure存储