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
