I've got an ASP.NET Core MVC app, hosted on Azure websites, where I've implemented Session and Identity. My problem is, after 30 minutes, I get logged out. It doesn't matter if I've been active in the last 30 minutes or not.
Doing some searching, I found that the issue is the SecurityStamp stuff, found here. I've tried implementing this by doing the following:
Here's my UserManager impelmentation with the security stamp stuff:
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);
}
}
Here's my ConfigureServices method on 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);
}
And lastly, here's my Configure method on 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?}");
});
}
What's wrong with my implementation here?
UPDATE: What a second...I noticed my UserManager is not inheriting from any interfaces for the security stamp stuff, is that what's needed?