Reputation: 1552
I am trying to get some custom field values from my authentication ticket by running the following code in my controller -
[HttpPost]
public ActionResult Add(AddCustomerModel customer)
{
customer.DateCreated = DateTime.Now;
customer.CreatedBy = ((CustomPrincipal)(HttpContext.User)).Id;
customer.LastUpdated = DateTime.Now;
customer.LastUpdateBy = ((CustomPrincipal)(HttpContext.User)).Id;
if (ModelState.IsValid)
{
_customerService.AddCustomer(customer);
return RedirectToAction("Index");
}
return View(customer);
}
When I try and set the CreatedBy field for the new customer, I get the following error -
Unable to cast object of type 'System.Security.Principal.GenericPrincipal' to type 'GMS.Core.Models.CustomPrincipal'.
My userData field within the FormsAuthenticationTicket is set with a JSON string which contains two fields - Id and FullName.
Here is my login method on the controller -
[HttpPost]
[AllowAnonymous]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (Membership.ValidateUser(model.EmailAddress, model.Password))
{
LoginModel user = _userService.GetUserByEmail(model.EmailAddress);
CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
serializeModel.Id = user.ID;
serializeModel.FullName = user.EmailAddress;
//serializeModel.MergedRights = user.MergedRights;
JavaScriptSerializer serializer = new JavaScriptSerializer();
string userData = serializer.Serialize(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
user.EmailAddress,
DateTime.Now,
DateTime.Now.AddHours(12),
false,
userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
return RedirectToAction("Index", "Dashboard");
}
return RedirectToAction("Index");
}
Any ideas where I am going wrong?
Upvotes: 4
Views: 4759
Reputation: 41
You need to create and AuthenticationFilter to change your GenericPrincipal to your CustomPrincipal
public class FormAuthenticationFilter : ActionFilterAttribute, IAuthenticationFilter
{
private readonly IResolver<HttpContextWrapper> httpContextWrapper;
private readonly IResolver<ISecurityProvider> securityProviderResolver;
public FormAuthenticationFilter(IResolver<HttpContextWrapper> httpContextWrapper, IResolver<ISecurityProvider> securityProviderResolver)
{
this.httpContextWrapper = httpContextWrapper;
this.securityProviderResolver = securityProviderResolver;
}
public void OnAuthentication(AuthenticationContext filterContext)
{
if (filterContext.Principal != null && !filterContext.IsChildAction)
{
if (filterContext.Principal.Identity.IsAuthenticated &&
filterContext.Principal.Identity.AuthenticationType.Equals("Forms", StringComparison.InvariantCultureIgnoreCase))
{
// Replace form authenticate identity
var formIdentity = filterContext.Principal.Identity as FormsIdentity;
if (formIdentity != null)
{
var securityProvider = this.securityProviderResolver.Resolve();
var principal = securityProvider.GetPrincipal(filterContext.Principal.Identity.Name, formIdentity.Ticket.UserData);
if (principal != null)
{
filterContext.Principal = principal;
this.httpContextWrapper.Resolve().User = principal;
}
}
}
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
}
}
And then register that filter to GlobalFilter
GlobalFilters.Filters.Add(new FormAuthenticationFilter());
The HttpContextWrapper in my code is just the wrapper of HttpContext.Current. You can change it to whatever you need. And the IAuthenticationFilter only exist in MVC 5.
Upvotes: 0
Reputation: 451
To retrieve the userdata from cookies you can use the following code
FormsIdentity formsIdentity = HttpContext.Current.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = formsIdentity.Ticket;
string userData = ticket.UserData;
Upvotes: 4