locked
How to Validate Security Stamp in Asp.Net Core 2 RRS feed

  • Question

  • User1070941592 posted

    Hi guys,

    I've been on this for days now trying to figure out how to validate security stamp in Asp.Net Core 2 to automatically signout user from previous logins. Below is my ConfigureServices and Login Method. Thanks in advance.

    services.AddIdentity<GPayUsers, IdentityRole>(option =>
    {
      option.User.RequireUniqueEmail = false;
      option.Password.RequiredLength = PasswordRequiredLength;
      option.Password.RequireDigit = PasswordRequireDigit;
      option.Password.RequiredUniqueChars = PasswordRequiredUniqueChars;
      option.Password.RequireLowercase = PasswordRequireLowercase;
      option.Password.RequireNonAlphanumeric = PasswordRequireNonAlphanumeric;
      option.Password.RequireUppercase = PasswordRequireUppercase;
      option.Lockout.MaxFailedAccessAttempts = LoginMaxFailedAccessAttempts;
    }).AddEntityFrameworkStores<GPayContext>().AddDefaultTokenProviders();
    
    services.ConfigureApplicationCookie(option =>
    {
      option.ExpireTimeSpan = TimeSpan.FromMinutes(CookiesExpireMinute);
      option.LoginPath = new PathString("/Login");
      option.LogoutPath = new PathString("/Logout");
      option.AccessDeniedPath = new PathString("/Login");
      //option.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    });
    
    public async Task<IActionResult> Login(LoginViewModel model)
            {
                try
                {
                    if (ModelState.IsValid)
                    {
                        ApplicationSettings applicationSettings = context.ApplicationSettings.FirstOrDefault();
                        GPayUsers user = await userManager.FindByNameAsync(model.UserName.Trim());
                        if (user != null)
                        {
                            await userManager.UpdateSecurityStampAsync(user);
                            user.TwoFactorEnabled = applicationSettings.EnableTwoFactorAuthentication;
                            user.LockoutEnabled = true;
                            if (!string.IsNullOrWhiteSpace(user.Email)) user.EmailConfirmed = applicationSettings.EnableTwoFactorAuthentication;
                            if (!string.IsNullOrWhiteSpace(user.PhoneNumber)) user.PhoneNumberConfirmed = applicationSettings.EnableTwoFactorAuthentication;
                            if (string.Equals(user.Status.ToUpper(), Status.L.ToString())) user.LockoutEnd = DateTime.Now.AddMonths(1);
                            await userManager.UpdateAsync(user);
    
                            if (user.DatePasswordChanged.HasValue)
                            {
                                int dayDifference = context.DBDateTime().Subtract(user.DatePasswordChanged.Value).Days;
                                if (dayDifference >= applicationSettings.PasswordExpires)
                                {
                                    await signInManager.SignOutAsync();
                                    return RedirectToAction(nameof(UserController.ChangePassword), new { id = user.Id, userType = Status.E.ToString() });
                                }
                            }
    
                            var result = await signInManager.PasswordSignInAsync(user, model.Password, false, true);
    
                            if (result.Succeeded)
                            {
                                switch (user.Status.ToUpper())
                                {
                                    case "N":
                                        await signInManager.SignOutAsync();
                                        return RedirectToAction(nameof(UserController.ChangePassword), new { id = user.Id, userType = Status.N.ToString() });
                                    default:
                                        return RedirectToAction(nameof(HomeController.Dashboard), "Home");
                                }
                            }
                            else if (result.IsLockedOut)
                            {
                                user.Status = Status.L.ToString();
                                await userManager.UpdateAsync(user);
                                ModelState.AddModelError(string.Empty, "This account has been locked out, please contact your system administrator.");
                                return View(model);
                            }
                            else if (result.RequiresTwoFactor)
                            {
                                return RedirectToAction(nameof(UserController.LoginWithTwoFA));
                            }
                            else
                            {
                                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                                return View(model);
                            }
                        }
                        else
                        {
                            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                            return View(model);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError(string.Empty, ex.Message);
                    return View(model);
                }
                return View(model);
            }
    Friday, November 24, 2017 9:09 AM

Answers

  • User475983607 posted

    Set the security stamp validation interval to something small like 10 seconds.

    services.Configure<SecurityStampValidatorOptions>(options => 
        options.ValidationInterval = TimeSpan.FromSeconds(10));
    
    services.AddAuthentication()
        .Services.ConfigureApplicationCookie(options =>
        {
            options.SlidingExpiration = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
        });

    You'll want to remove the update security stamp in the login method otherwise, I believe, the new start up setting will force a login over and over.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 24, 2017 1:56 PM

All replies

  • User475983607 posted

    Set the security stamp validation interval to something small like 10 seconds.

    services.Configure<SecurityStampValidatorOptions>(options => 
        options.ValidationInterval = TimeSpan.FromSeconds(10));
    
    services.AddAuthentication()
        .Services.ConfigureApplicationCookie(options =>
        {
            options.SlidingExpiration = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
        });

    You'll want to remove the update security stamp in the login method otherwise, I believe, the new start up setting will force a login over and over.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 24, 2017 1:56 PM
  • User1070941592 posted

    Thanks a million times Mgebhard,

    It works as expected. I will mark it as answer.

    Friday, November 24, 2017 4:14 PM