In this article I am showing you the simplest way to implement FormsAuthentication in your MVC application. In this article I am going to use FormsAuthenticationTicket for encrypt and store logged in user data with FormsAuthenticaiton.
Step 1: Add "authentication mode="Forms"" under <system.web> tag in your web.config file. Modify your web.config file according to following code.
<authentication mode="Forms">
<forms name="BillAndPayCookie" defaultUrl="/Account/Index" loginUrl="/Account/Index"> </forms>
</authentication>
Step 2: Add new class named LoginModel.cs in your Models folder and paste the following code in this file.
public class LoginModel
{
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
public string ReturnUrl { get; set; }
public static void SetCookiesData(LoginModel model)
{
FormsAuthentication.SetAuthCookie(model.Email, false);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
model.Email,
DateTime.Now,
DateTime.Now.AddMinutes(30),
true,
"{name:'test',password:'123123'}",
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
HttpContext.Current.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
}
public static string DecryptCookie()
{
var httpCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (httpCookie == null)
{
return "";
}
//Here throws error!
var decryptedCookie = FormsAuthentication.Decrypt(httpCookie.Value);
if (decryptedCookie == null)
{
return "";
}
return decryptedCookie.UserData;
}
}
Step 3: Add new controller named "AccountController" and paste following code in this.
public class AccountController : Controller
{
// GET: Account
public ActionResult Index(string returnUrl)
{
LoginModel model = new LoginModel { ReturnUrl = returnUrl };
return View(model);
}
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (!ModelState.IsValid)
{
return View("Index");
}
if (model.Email == "sanjay@gmail.com" && model.Password == "sanjay")
{
LoginModel.SetCookiesData(model);
if (!string.IsNullOrEmpty(model.ReturnUrl))
{
return Redirect(model.ReturnUrl);
}
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Invalid email or password.");
}
return View("Index");
}
//[HttpPost]
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index");
}
}
Step 4: Add new view named Index.cshtml for AccountController.
@model BillAndPaySampleMVC.Models.LoginModel
@{
ViewBag.Title = "Index";
}
<div class="row">
@using (Html.BeginForm("Login", "Account", null, FormMethod.Post, new { }))
{
@Html.HiddenFor(m => m.ReturnUrl)
<div class="col-md-6 col-md-offset-3">
<h2>Login</h2>
<div class="form-group" ng-class="{ 'has-error': form.username.$dirty && form.username.$error.required }">
<label for="username">Username/Email</label>
@Html.TextBoxFor(m => m.Email, new { placeholder = "", @class = "form-control" })
</div>
<div class="form-group" ng-class="{ 'has-error': form.password.$dirty && form.password.$error.required }">
<label for="password">Password</label><a href="#ForgotPassword" class="btn btn-link">Forgot Password</a>
@Html.PasswordFor(m => m.Password, new { placeholder = "", @class = "form-control" })
</div>
<div class="form-actions">
<input type="submit" class="btn btn-primary" value="Login" />
</div>
<div class="form-actions">
<span style="color:red">
@Html.ValidationSummary()
</span>
</div>
</div>
}
</div>
Step 5: For the add the roles in every request you need to authenticate every request through Global.asax.cs file. Paste the following method in your Global.asax.cs file.
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity id =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Get the stored user-data, in this case, our roles
string userData = "admin,user";
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
}
}
The following method we can use to rename the forms authentication cookie name dynamically.
private static void ResetCookieName(string email)
{
// This will enforce that FormsAuthentication class is loaded from configuration settings for the application.
FormsAuthentication.Initialize();
// The new cookie name whatever you need can go here, I needed some value from my application setting to be prefixed so I used it.
string newCookieName = "NewCookieName";
// Modifying underlying baking field that points to FormsAuthentication.FormsCookieName
Type type = typeof(FormsAuthentication);
System.Reflection.FieldInfo field = type.GetField("_FormsName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
field.SetValue(null, newCookieName);
}
No comments:
Post a Comment