Currently, I am working on a web application, based on the roles we have to display the controls in the UI. Roles are stored in the DB, whenever the user logs in, by fetching the user Id, I will hit the DB and get the user role and store it in the cookie. So, for the next request, I will fetch the user role from the User.IsInRole() and proceed with the logic same will happens in the view. This entire thing is working fine with the single server but when it comes to load balancer, this behaving weirdly and intermittently it's giving issue, as User.IsInRole() is returning false sometime.
The code in my controller:
public ActionResult IsValidUser(string userName)
{
try
{
if (HttpContext!=null&& HttpContext.Request.Headers["username"] != null)
{
userName = HttpContext.Request.Headers["username"];
}
//Get the roles by sending the user name
userRole = _processor.GetUserRole(userName);
UserViewModel user = new UserViewModel()
{
UserName = userName,
Role = userRole
};
if (!string.IsNullOrEmpty(user.Role))
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.UserName, DateTime.Now, DateTime.Now.AddMinutes(2880), true, user.Role, FormsAuthentication.FormsCookiePath);
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
if(Response!=null)
Response.Cookies.Add(cookie);
if (!string.IsNullOrEmpty(Request.Form["ReturnUrl"]))
{
return View("Error");
}
else
{
return RedirectToAction("Index");
}
}
else
{
return View("Error")
}
}
else
return RedirectToAction("Search");
}
catch (Exception ex)
{
return View("Error);
}
}
The code in Global.asax.cs
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;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
}
}
the code in my controller to do the logic:
public FileContentResult ViewAttachment(string attachmentName, int attachmentId)
{
if (ConfigurationManager.AppSettings["Environment"] != Constants.ProductionEnvironment ||
(User.IsInRole(Constants.Administrator) || User.IsInRole(Constants.Contributor) || User.IsInRole(Constants.Member)))
{
//Logic here
return File(bytes, mimeType);
}
else
{
_logger.WriteInformation("Not authorized");
return File(bytes, mimeType);
}
}
I am not sure what mistake is there but this is not working in load balancer sometimes it is showing "User is not authorized" but in actual user is authorized. Is it because of cookies or load balancer? Any help would be appreciated. Thanks in advance.