无法在Forms身份验证票证上检索UserData

时间:2015-01-11 15:48:41

标签: asp.net-mvc asp.net-mvc-4 authentication

我试图通过在我的控制器中运行以下代码来从我的身份验证票证中获取一些自定义字段值 -

[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);
    }

当我尝试为新客户设置CreatedBy字段时,我收到以下错误 -

  

无法将“System.Security.Principal.GenericPrincipal”类型的对象强制转换为“GMS.Core.Models.CustomPrincipal”。

FormsAuthenticationTicket中的我的userData字段设置了一个JSON字符串,其中包含两个字段 - Id和FullName。

这是我在控制器上的登录方法 -

    [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");
    }

我出错的任何想法?

2 个答案:

答案 0 :(得分:2)

要从Cookie中检索用户数据,您可以使用以下代码

FormsIdentity formsIdentity = HttpContext.Current.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = formsIdentity.Ticket;
string userData = ticket.UserData;

答案 1 :(得分:0)

您需要创建和AuthenticationFilter才能将GenericPrincipal更改为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)
    {
    }
}

然后将该过滤器注册到GlobalFilter

GlobalFilters.Filters.Add(new FormAuthenticationFilter());

我的代码中的HttpContextWrapper只是HttpContext.Current的包装器。您可以将其更改为您需要的任何内容。 IAuthenticationFilter仅存在于MVC 5中。