1

大家好,我正在使用自定义会员提供程序和自定义角色提供程序。它正在正确使用这些登录。我还实现了自己的 Membership 用户对象,这样我就可以访问其他用户信息,并且每次更改页面时都不需要加载所有数据,但我目前无法使其正常工作。下面是我的用户对象:

public class User : MembershipUser
{
    [Required(ErrorMessage = "Username cannot be blank")]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required(ErrorMessage = "Password cannot be blank")]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "User ID")]
    public long UserID { get; set; }

    [Display(Name = "Family Name")]
    [StringLength(50, ErrorMessage = "Family name cannot be longer than 50 characters")]
    public string FamilyName { get; set; }

    [Display(Name = "Given Name")]
    [StringLength(50, ErrorMessage = "Given name cannot be longer than 50 characters")]
    public string GivenName { get; set; }

    public Company Company { get; set; }

    public virtual IIdentity Identity { get; set; }
}

当用户登录时,我调用以下登录方法:

    [AllowAnonymous]
    [HttpPost]
    public ActionResult Login(User model, string returnUrl)
    {
        FormsAuthentication.SignOut();
        if(Membership.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, true);
            return RedirectToAction("Index", "");
        }
        ViewBag.Message = "Failed to login";
        return View();
    }

但是当我调用HttpContext.User索引时,它只包含名称/ID,而不是我的用户对象的其余部分。我需要创建自定义FormAuthentication对象吗?还是将所有这些用户信息存储在HttpContext.Session对象中的标准过程?或者让我的用户扩展System.Security.Principle.IPrinciple?甚至在Controller.TempData? 或者其他我不熟悉的地方。我不想每次都访问数据库来加载用户数据。

抱歉,如果这些是明显的问题,我对 Web 开发还很陌生,并且不确定做这些事情的通用方法是什么。尝试使用 in build Authorize 属性。

4

1 回答 1

5

我通过实现自己的身份来做到这一点。这样就可以轻松添加我需要的任意数量的属性。下面是一个带有自定义属性friendlyName 的代码示例

public class Identity : IIdentity
    {
        public Identity(int id, string name, string friendlyName, string roles)
        {
            this.ID = id;
            this.Name = name;
            this.FriendlyName = friendlyName;
            this.Roles = roles;
        }



  public Identity(string name, string data)
    {
        if (string.IsNullOrWhiteSpace(data))
            throw new ArgumentException();

        string[] values = data.Split('|');
        if (values.Length != 3)
            throw new ArgumentException();

        this.Name = name;
        this.ID = Convert.ToInt32(values[0]);
        this.FriendlyName = values[1];
        Roles = values[2];
    }

    public string AuthenticationType
    {
        get { return "Custom"; }
    }

    public bool IsAuthenticated
    {
        get { return true; }
    }

    public override string ToString()
    {
        return FriendlyName;
    }

    public string GetUserData()
    {
        return string.Format("{0}|{1}|{2}", ID, FriendlyName, Roles);
    }


    public int ID { get; private set; }
    public string Name { get; private set; }
    public string FriendlyName { get; private set; }
    public string Roles { get; private set; }
}

//in controller on login action:
        Identity id = new Identity(user.ID,  user.Username, "some friendly name", user.Roles);
        DateTime expire = DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes);
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(id.ID, user.Username, DateTime.Now, expire, false, id.GetUserData());
        string hashTicket = FormsAuthentication.Encrypt(ticket);
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);
        HttpContext.Response.Cookies.Add(cookie);

在 global.asax 中,您有:

public override void Init()
        {
            base.Init();
            PostAuthenticateRequest += new EventHandler(MvcApplication_PostAuthenticateRequest);
        }

    void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            if (authTicket == null || authTicket.Expired)
                return;

            Identity id = new Identity(authTicket.Name, authTicket.UserData);
            Principal user = new Principal(id);
            Context.User = user;
            Thread.CurrentPrincipal = user;
        }
    }
于 2012-09-12T07:28:37.990 回答