Hi I am trying to get a users role and set it to a cookie in my application
I have the following code which works
public ActionResult Index()
{
var user = User.Identity.Name; // set by 3rd party central login in manager
// key to check that we are in our environment with 3rd party login set up
if (ConfigurationManager.AppSettings["IsNGDC"] == "true")
{
// ActiveKey login
if (user.Contains("uid="))
{
var endIndex = user.IndexOf(",ou");
var userEmail = user.Substring(4, endIndex - 4);
user = userEmail;
}
SetAuthenticationCookie(user);
}
// view model is not needed I could just pass in a string
var viewModel = new SiteminderViewModel { Username = user };
if (ModelState.IsValid)
{
this.AssignRoles(viewModel);
return this.View();
}
return View(viewModel);
}
I need to change this because I am using a dynamic Navigation bar that shows different Items depending on the users role and it does not show the correct Nav bar until the user refreshes the page. I think this is because the view uses the cookie and the view is being rendered in the same action that sets the cookie.
I want to split this into 2 actions in my controller as follows
public void LogIn()
{
var user = User.Identity.Name; // set by 3rd party central login in manager
// key to check that we are in our environment with 3rd party login set up
if (ConfigurationManager.AppSettings["IsNGDC"] == "true")
{
// ActiveKey login
if (user.Contains("uid="))
{
var endIndex = user.IndexOf(",ou");
var userEmail = user.Substring(4, endIndex - 4);
user = userEmail;
}
SetAuthenticationCookie(user);
}
// view model is not needed I could just pass in a string
var viewModel = new SiteminderViewModel { Username = user };
this.AssignRoles(viewModel);
// default URL in Index action for this controller
this.Response.Redirect(FormsAuthentication.DefaultUrl, false);
}
public ActionResult Index()
{
ViewBag.Message = "Home App Description here";
return this.View();
}
When I try this it looks like the Cookie hasn't been set. Unfortunately I can only test this code on a replication of our Production Environment because of the 3rd party login so I have limited debug info. As far as I can tell the problem seems to be with how I am redirecting.
I have provided the methods I use cor creating the cookie and assigning the roles bellow.
Additional Info
private void SetAuthenticationCookie(string username)
{
var tkt = new FormsAuthenticationTicket(1, username, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20), true, string.Empty);
var encryptedTkt = FormsAuthentication.Encrypt(tkt);
var formsCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTkt);
this.Response.Cookies.Add(formsCookie);
}
private void AssignRoles(SiteminderViewModel viewModel)
{
var authCookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
var ticket = authCookie != null ? FormsAuthentication.Decrypt(authCookie.Value) : new FormsAuthenticationTicket(1, viewModel.Username, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20), true, string.Empty);
var user = this.userRepository.GetUser(viewModel.Username);
if (user != null)
{
var principleProperties = new PrincipleProperties(ticket.UserData)
{
UserName = user.Email,
UserRole = user.UserGroup.Role.Name.Replace(" ", string.Empty),
ContextId = contextRepository.GetContextByDataOwnerGroupId(user.UserGroupId)
};
if (user.DeletedIndicator)
{
principleProperties.UserRole = string.Empty;
}
this.SetPrinciple(ticket, principleProperties);
}
}
private FormsAuthenticationTicket SetPrinciple(FormsAuthenticationTicket ticket, PrincipleProperties properties)
{
var newticket = new FormsAuthenticationTicket(
ticket.Version,
ticket.Name,
ticket.IssueDate,
ticket.Expiration,
ticket.IsPersistent,
properties.Serialize(),
ticket.CookiePath);
var encryptedTkt = FormsAuthentication.Encrypt(newticket);
var formsCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTkt);
this.Response.Cookies.Set(formsCookie);
var referenceDataIdentity = new ReferenceDataIdentity(ticket);
var principle = new ReferenceDataPrinciple(referenceDataIdentity, properties);
Thread.CurrentPrincipal = principle;
return newticket;
}
The RedirectToAction() Method This method is used to redirect to specified action instead of rendering the HTML. In this case, the browser receives the redirect notification and make a new request for the specified action.
Redirect() method The Rediect() method is available to your controller from the ControllerBase class. It accepts a target URL where you would like to go. For example, consider the following two actions of HomeController. The Index() action invokes the Redirect() method by specifying the URL of the Privacy() action.
return RedirectToAction() To redirect to a different action which can be in the same or different controller. It tells ASP.NET MVC to respond with a browser to a different action instead of rendering HTML as View() method does.
The solution to this was that the cookie wasn't being added to the browser because I was redirecting before the cookie reached the client side the solution was to have the Login Action return a blank view and then from inside the view redirect to the Index action the final version of my code ended up as follows NOTE: Login changed to AuthenticateUser
public ActionResult Index()
{
var authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
if (ticket != null && ticket.UserData != string.Empty)
{
return this.View();
}
}
return RedirectToAction("AuthenticateUser");
}
public ActionResult AuthenticateUser()
{
// set by Site minder
var user = User.Identity.Name;
// ActiveKey login
if (user.Contains("uid="))
{
var endIndex = user.IndexOf(",ou");
var userEmail = user.Substring(4, endIndex - 4);
user = userEmail;
}
SetAuthenticationCookie(user);
var viewModel = new SiteminderViewModel { Username = user };
this.AssignRoles(viewModel);
return this.View();
}
and the view is. There is no HTML to display so the redirect is not noticeable.
@{
ViewBag.Title = "AuthenticateUser";
Layout = null;
Response.Redirect( Url.Action("Index", "Home"), false);
}
This code is checking that there is a cookie and that the user data isn't empty, if theses checks pass it shows the user the home page. Otherwise it redirects to the authentication action that gets the email address that was set in the browser by our 3rd party central login software and gets the users details from the users details. If the user is not in our user table they are given basic access rights.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With