ASP.NET MVC 4 Authorization – How to handle custom roles ?

 Basically there is ready scheme, which comes with the ASP.NET MVC4 template, in which there is an existing authentication with account from other websites (Facebook, Google…) which is called oAuth. But I like writing my own authentication so i did  check out the existing authentication and how i can create my own:

  1.  I used Forms Authentification. In it the browser asks the user for his name and password and after he confirms that the user is existing he gives a ticket to the user which is stored in a encrypted cookie.In this ticket you can put name, roles, website and others. The other way is to take the data from the DB every time. This cookie is checked every time when the user enters another part of your website.
  2.  So if you don’t want to check every time on every method the name of the user and his roles you can create a configuration in Global.asax , which is the file which executes every time when the user wants to go to another page. Here you can override the method:
    protected void Application_OnAuthenticateRequest(Object src, EventArgs e)
    and you can check in it the user roles:
protected void Application_OnAuthenticateRequest(Object src, EventArgs e) 

{
//Взимаме текущия контекст и проверяваме дали потребителя е аутентифициран и
//дали е чрез Forms аутентификация
HttpContext currentContext = HttpContext.Current;

if (HttpContext.Current.User != null)

{

if (HttpContext.Current.User.Identity.IsAuthenticated)

{

if (HttpContext.Current.User.Identity is FormsIdentity)

{
//We create a new identity from the cookie
FormsIdentity id = HttpContext.Current.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string roles = "administrator";
HttpContext.Current.User = new GenericPrincipal(id, roles.Split(','));
//System.Threading.Thread.CurrentPrincipal = new GenericPrincipal(id, roles.Split(','));
}

}

}

}



     3. You create a new controller, new method and a new view, which has a login form. When the user sends the login account and pass you just check if they are in the database. If you are debugging place a breakpoint at the new method which is in Global.asax and you will see that after each request the breakpoint  will be executed. If we have the user – just add a new cookie, with data like the name and the roles of the user and redirect him back to the page, where he came from. Example in code:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
using (BGTravelEntities db = new BGTravelEntities())
{
string username = model.UserName;
string password = model.Password;

bool userValid = db.Users.Any(x => x.UserName == username && x.Password == password);

if (userValid)
{
string roles = db.Users.FirstOrDefault(x => x.UserName == username).Roles;

DateTime cookieIssuedDate = DateTime.Now;

var ticket = new FormsAuthenticationTicket(0,
model.UserName,
cookieIssuedDate,
cookieIssuedDate.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
false,
roles,
FormsAuthentication.FormsCookiePath);

string encryptedCookieContent = FormsAuthentication.Encrypt(ticket);

var formsAuthenticationTicketCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookieContent)
{
Domain = FormsAuthentication.CookieDomain,
Path = FormsAuthentication.FormsCookiePath,
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL
};

System.Web.HttpContext.Current.Response.Cookies.Add(formsAuthenticationTicketCookie);

return RedirectToLocal(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}

}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}

return View(model);
}

If you CANNOT detected the user roles please check the Web.config: <appSettings> <add key=”enableSimpleMembership” value=”false” /> .

You may also like...