|
private TimeSpan IdleSessionTimeout = TimeSpan.FromMinutes(5); // Sign out after inactivity for this amount of time. |
|
private TimeSpan CookieLifespan = TimeSpan.FromMinutes(60); // How long to 'Remember me' |
|
|
|
|
|
public void ConfigureServices(IServiceCollection services) |
|
{ |
|
// Add identity types |
|
services.AddIdentity<ApplicationUser, ApplicationRole>(options => |
|
{ |
|
options.Password.RequiredLength = 8; |
|
options.Password.RequireLowercase = true; |
|
options.Password.RequireUppercase = true; |
|
options.Password.RequireDigit = false; |
|
options.Password.RequireNonAlphanumeric = false; |
|
}).AddDefaultTokenProviders(); |
|
|
|
services.AddSingleton<IUserStore<ApplicationUser>, IdentityRepositoryMapping>(); |
|
services.AddSingleton<IUserPasswordStore<ApplicationUser>, IdentityRepositoryMapping>(); |
|
services.AddSingleton<IPasswordHasher<ApplicationUser>, IdentityRepositoryMapping>(); |
|
services.AddSingleton<IUserClaimsPrincipalFactory<ApplicationUser>, UserPrincipalFactory>(); |
|
|
|
// Not currently using roles |
|
// var repositoryRoleMapping = new RoleRepositoryMapping(); |
|
// services.AddSingleton<IRoleStore<ApplicationRole>>(repositoryRoleMapping); |
|
|
|
services.Configure<SecurityStampValidatorOptions>(options => |
|
{ |
|
options.ValidationInterval = TimeSpan.Zero; |
|
}); |
|
|
|
// must be defined after AddIdentity otherwise the values wll get overwritten |
|
services |
|
.AddAuthentication() |
|
.AddCookie(options => |
|
{ |
|
options.ExpireTimeSpan = IdleSessionTimeout; |
|
options.Cookie.MaxAge = CookieLifespan; |
|
options.Cookie.Expiration = CookieLifespan; |
|
options.SlidingExpiration = true; |
|
}); |
|
|
|
... |
|
} |
|
|
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime) |
|
{ |
|
// The request logger is first so that the log entries happen before any other code has a chance to exception. |
|
app.UseMiddleware<RequestLogger>(); |
|
|
|
if (env.IsDevelopment()) |
|
{ |
|
app.UseDeveloperExceptionPage(); |
|
app.UseBrowserLink(); |
|
} |
|
else |
|
{ |
|
app.UseExceptionHandler("/Error"); |
|
} |
|
|
|
app |
|
.UseStaticFiles() |
|
.UseAuthentication(); |
|
} |
|
|
|
public class IdentityRepositoryMapping : IUserStore<ApplicationUser>, |
|
IUserPasswordStore<ApplicationUser>, |
|
IUserLoginStore<ApplicationUser>, |
|
IPasswordHasher<ApplicationUser>, |
|
IUserSecurityStampStore<ApplicationUser> |
|
|
|
{ |
|
#region IUserSecurityStampStore Implementation |
|
|
|
public Task SetSecurityStampAsync(ApplicationUser user, string stamp, CancellationToken cancellationToken) |
|
{ |
|
// TODO |
|
return Task.CompletedTask; |
|
} |
|
|
|
public Task<string> GetSecurityStampAsync(ApplicationUser user, CancellationToken cancellationToken) |
|
{ |
|
// TODO |
|
return Task.FromResult(user.UserId); |
|
} |
|
|
|
#endregion |
|
} |
|
|
|
// POST: /Account/Login |
|
[HttpPost("Login")] |
|
[AllowAnonymous] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) |
|
{ |
|
ViewData["ReturnUrl"] = returnUrl; |
|
|
|
if (ModelState.IsValid) |
|
{ |
|
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, lockoutOnFailure: false); |
|
|
|
if (result.Succeeded) |
|
{ |
|
return RedirectToLocal(returnUrl); |
|
} |
|
else if (result.IsLockedOut) |
|
{ |
|
return View("Lockout"); |
|
} |
|
else |
|
{ |
|
ModelState.AddModelError(string.Empty, "Invalid login attempt."); |
|
return View(model); |
|
} |
|
} |
|
|
|
return View(model); |
|
} |
|
|