How to do autologin in MVC and which is the best method to securely save Cookies in asp.net MVC?
please help
You can keep the user logged in like Gmail does by using Remember me and increasing timeout time in Web.Config
<system.web>
<authentication mode="Forms">
<forms timeout="20160"/>
</authentication>
</system.web>
Suppose when user tries to access Index ActionMethod, you can check if it's logged in using the C# code in controller like
public ActionResult CheckLogin()
{
if (Request.IsAuthenticated)
{
//user is still logged in , do something
}
else
{
//redirect to login page
}
return View("DefaultView");
}
Or check the link below for the full implementation of MVC authentication
http://www.dotnetcurry.com/aspnet-mvc/1229/user-authentication-aspnet-mvc-6-identity
If you are using ASP.NET MVC 5, you can take a look at this method AccountController.cs (Default code if you select MVC template while creating new application)
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.Email, model.Password);
if (user != null)
{
//this line, second argument is used to keep user logged in if we check remember Me
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
basically, this line, second argument is used to keep user logged in if we check remember Me
await SignInAsync(user, model.RememberMe);
now, If you don't want user to provide remember me and just want to keep every user logged in, use true in second argument of above line, which will force persistence
await SignInAsync(user, true);
Complete code
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
//check for validation
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.Email, model.Password);
if (user != null)
{
await SignInAsync(user, true);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// error , show login page with Validation errors
return View(model);
}
I feel it is better to use auto-generated template code, as this is generated by microsoft template, which is generated keeping security in mind also.
thanks for help :)
i checked on page load if cookie is present or not then do auto login .
can u tell me what is good technique to encrypt the data in cookie like base 64 encoding or sumthing else?
Base64 is good, but if you like you can also Encrypt/decrypt cookie using C# using your own method
private string Encrypt(string clearText)
{
string EncryptionKey = "MAKV2SPBNI99212";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
private string Decrypt(string cipherText)
{
string EncryptionKey = "MAKV2SPBNI99212";
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
But usually the method which is used in MVC is like code below
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
logon.Username,//username
DateTime.Now,
DateTime.Now.AddDays(30),//duration of auto-login
true, //here you set remember me for auto-login
userData, //email/pass
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket, using Offical Microsoft method
string encTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
Base 64 way to encyrpt cookies in C#
As .Net 4.5 has MachineKey.Protect()
and MachineKey.Unprotect()
. Which is
good to use instead of creating your own method like above.
System.Web.Security.MachineKey
C# code using Base64 and above introduced MachineKey would be as below:
//Encrypt
Convert.ToBase64String(MachineKey.Protect(Encoding.UTF8.GetBytes("your cookie value")))
//Decrypt
Encoding.UTF8.GetString(MachineKey.Unprotect(Convert.FromBase64String("your cookie value")))
Subscribe to our weekly Newsletter & Keep getting latest article/questions in your inbox weekly