Home > Mobile >  SignInManager.SignInAsync(user, false) does not set user in context
SignInManager.SignInAsync(user, false) does not set user in context

Time:10-26

I am working on a financial project which needs high security for signing user in. In this project I didn't use default authentication when creating project and I have implement it manually. Now when user logs in his panel all functionalities run without error and SignInManager signs him in normally but when I want to redirect him to his dashboard with [Authorize] annotation again hi redirects to Login page. What is the problem? It is about implementing identity manually?

here is my code for login:

public async Task<IActionResult> Login(LoginViewModel model)
{
    try
    {
        string targetUrl = "";
        if (ModelState.IsValid)
        {
            var user = await userManager.FindByEmailAsync(model.Email);
            if (user == null)
            {
                _logger.Log(LogLevel.Warning, $"User ({model.Email}) tried to login with went wrong info");
                return Json(new { result = "error", target = "login", message = "Wrong Email or Password. Please fill the form with valid information" });
            }
            var loginAttempt = await signInManager.CheckPasswordSignInAsync(user, model.Password, true);
            if (loginAttempt.Succeeded)
            {
                if (user.TwoFactorEnabled)
                {
                    TempData["loginInfo"] = JsonConvert.SerializeObject(user);
                    TempData.Keep("loginInfo");
                    targetUrl = "/Account/TwoStepVerification";
                }
                else
                {
                    await signInManager.SignInAsync(user, false);
                    var login = new UserLogin
                    {
                        IpAddress = HttpContext.Connection.RemoteIpAddress.ToString(),
                        TimeStamp = DateTime.Now.Ticks,
                        UserId = user.Id
                    };
                    DbContext.UserLogins.Add(login);
                    await DbContext.SaveChangesAsync();
                    targetUrl = model.ReturnUrl ?? "/Account/Dashboard";
                }
                return Json(new { result = "success", target = "login", url = targetUrl, message = "You have successfully logged in. Wait some seconds..." });
            }
            return Json(new { result = "error", target = "login", message = "Wrong Email or Password." });
        }
        return Json(new { result = "error", target = "register", message = "Something went wrong. Bad input" });
    }
    catch (Exception exc)
    {
        _logger.Log(LogLevel.Critical, $"Failed Login : {exc.Message}");
        return Json(new { result = "error", target = "register", message = "Something went wrong. Please try again after some minutes" });
    }
}

here is two step verification :

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> TwoStepVerification(string code)
{
    TempData.Keep("loginInfo");
    if (code == null)
    {
        return Json(new { result = "error", target = "2faverified", message = "Please 2fa code" });
    }            
    var user = JsonConvert.DeserializeObject<ApplicationUser>(TempData["loginInfo"].ToString());            
    GoogleAuthenticatorHelper google2FA = new(user.Id, user.Email);
    if (google2FA.IsUserInputValid(code))
    {
        await signInManager.SignInAsync(user, false);
        var login = new UserLogin
        {
            IpAddress = HttpContext.Connection.RemoteIpAddress.ToString(),
            TimeStamp = DateTime.Now.Ticks,
            UserId = user.Id
        };
        DbContext.UserLogins.Add(login);
        await DbContext.SaveChangesAsync();
        return Json(new { result = "success", url = "/Account/Dashboard", target = "2faverified", message = "You have successfully validate 2fa. Please wait..." });
    }
    return Json(new { result = "error", target = "2faverified", message = "Validation failed." });
}

here is ConfigureService in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();

    services.AddDefaultIdentity<ApplicationUser>(options =>
    {
        options.Password.RequireDigit = true;
        options.Password.RequireUppercase = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;

        options.User.RequireUniqueEmail = true;
        options.SignIn.RequireConfirmedEmail = false;

    }).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
    services.ConfigureApplicationCookie(options =>
    {
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(30);

        options.LoginPath = new PathString("/Account/Login");
        options.AccessDeniedPath = new PathString("/Account/AccessDenied");

        options.SlidingExpiration = true;
    });

    services.Configure<DataProtectionTokenProviderOptions>(options =>
    {
        options.TokenLifespan = TimeSpan.FromDays(1);
    });

    services.AddControllersWithViews();
}

CodePudding user response:

Sorry I had forgotten to add app.UseAuthentication(); code to my Configure function in Startup.cs

  • Related