ASP.NET MVC 3 MembershipProvider

时间:2012-06-20 23:55:32

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-membership

我目前正在使用ASP.NET MVC 3开发一个站点,我正在使用Nhibernate。我创建了一个自定义MembershipProvider,如下所述。

我的问题是在ValidateUser方法中在会话中记录用户身份验证并在GetUser中检索它的时间。

从我注意到你不能在ValidateUser中使用Session,但使用Cache是​​不正确的,因为存储不是每个用户会话。

我该怎么办?

class MyMembershipProvider : MembershipProvider
{
    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
        var membershipUser = MyMembershipUser)HttpContext.Current.Cache.Get(username);

        // Is not possible
        // var membershipUser = (MyMembershipUser) HttpContext.Current.Session[username];

        return membershipUser;
    }

    public override bool ValidateUser(string username, string password)
    {
        var usuario = UsuarioRepository.GetUsuarioAuthentication(username, password);

        if (usuario != null)
        {
            HttpContext.Current.Cache.Add(username, new MyMembershipUser(usuario.Id, usuario.Email), null,
                                          Cache.NoAbsoluteExpiration, FormsAuthentication.Timeout,
                                          CacheItemPriority.Default, null);

            // Is not possible 
            // HttpContext.Current.Session.Add(username, new MyMembershipUser(usuario.Id, usuario.Email));

            return true;
        }

        return false;
    }

}

4 个答案:

答案 0 :(得分:5)

当您使用ASP.NET身份验证与表单身份验证时,根本不涉及会话。

用户成功通过身份验证后,只需致电

即可
FormsAuthentication.SetAuthCookie() 

并自动为您创建身份验证Cookie。不要在ValidateUser()中调用它,而是从调用ValidateUser()的客户端代码中调用它。

身份验证cookie完全独立于会话cookie。

有关详细信息,请参阅MSDN上的Forms Authentication

如果要缓存已验证用户的用户详细信息,请再次在调用Membership.ValidateUser()的客户端代码中完成此操作,而不是在成员资格提供程序本身中完成。 会员提供商GetUser()和ValidateUser()应该按照他们的名字建议,并且没有任何其他副作用。

答案 1 :(得分:1)

您不希望从会话中获取用户。 GetUser用于从数据库中检索用户 - 返回填充的MembershipUser对象。

答案 2 :(得分:1)

这两种方法的实现应该只查询您的数据库并返回MembershipUser或验证用户名密码 - 不要担心HttpContext

我不知道您UsuarioRepository实施的具体细节,所以我刚刚提出了一些方法,但您应该像这样对您的提供商进行编码:

class MyMembershipProvider : MembershipProvider
{
    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
        var usuario = UsuarioRepository.GetUserByUserName(username);
        return new MyMembershipUser(usuario.Id, usuario.Email);
    }

    public override bool ValidateUser(string username, string password)
    {
        return UsuarioRepository.ValidateUser(username, password);              
    }
}

UsuarioRepository.GetUserByUserName(username)方法只返回具有给定用户名的用户,而UsuarioRepository.ValidateUser(username, password)如果密码对于给定用户名是正确的,则应返回true。存储库将处理获取会话和执行查询。

然后,为了提高提供程序的性能,您可以使用NHibernate的一些内置缓存功能,通过修改UsuarioRepository方法来使用缓存来确保缓存这些查询的结果。然后,对这些方法的多次调用将不会有性能损失。

答案 3 :(得分:1)

您是否关注查找有关用户的信息?

使用MVC,您可以随时拨打

        User.Identity.Name

这将为您提供用户的当前用户名。

正如上面提到的@Saille,您只需关注创建MembershipUser的基础知识,并在创建自己的自定义成员资格提供程序时验证MembershipUser

完成基本操作并创建提供程序后,您可以在成功用户登录后将信息存储到Session