I am writing an MVC 4 web application with custom authentication and authorisation. When a user logs into the site, I create a a FormsAuthenticationTicket and store it in a cookie
public void SignIn(string userName, bool createPersistentCookie, string UserData)
{
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
// Create and tuck away the cookie
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddDays(15), createPersistentCookie, UserData);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(authTicket);
//// Create the cookie.
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
HttpContext.Current.Response.Cookies.Add(faCookie);
}
The UserData string will be a pipe delimited string and it will always contain at least two items, UserID | UserRole. A user can be assigned to one or more roles, therefore, the UserData could look like this UserID | UserRole | UserRole | UserRole
I then have my own custom generic principal in Global.asax
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// Get the authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
// If the cookie can't be found, don't issue the ticket
if (authCookie == null) return;
// Get the authentication ticket and rebuild the principal
// & identity
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] UserData = authTicket.UserData.Split(new Char[] { '|' });
GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity, UserData);
Context.User = userPrincipal;
}
This all works fine, however, within my application, if a user has multiple roles, when they log in, I need to list their roles, and then let them select only one role to go and perform functionality based on the selected role.
I was thinking, to do this, maybe I could pass the role the user selects to a method, get their FormsAuthenticationTicket and update the UserData to reflect the role they have choosen. For example, a UserData string is created with 1|Manager|Applicant, then I need to list both roles and ask the user which role they want to perform functionality under, they select Manager and I then update their UserData within their FormsAuthenticationTicket to 1|Manager.
Is this even possible, or maybe there is a better way of doing this?
Any help would be greatly appreciated.
Thanks everyone.