3

我目前正在使用 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

4 回答 4

5

当您使用带有表单身份验证的 ASP.NET 成员身份时,根本不涉及会话。

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

FormsAuthentication.SetAuthCookie() 

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

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

有关详细信息,请参阅MSDN 上的表单身份验证。

如果您想缓存经过身份验证的用户的用户详细信息,这应该在调用 Membership.ValidateUser() 的客户端代码中完成,而不是在成员资格提供程序本身中完成。成员资格提供者 GetUser() 和 ValidateUser() 应该按照他们的名字所暗示的那样做,并且没有任何其他副作用。

于 2012-06-21T00:46:26.743 回答
1

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

于 2012-06-21T00:36:22.683 回答
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。存储库将处理获取会话并进行查询。

UsuarioRepository然后,为了提高您的提供者的性能,您可以使用 NHibernate 的一些内置缓存功能,通过修改您的方法以使用缓存来确保它缓存这些查询的结果。然后对这些方法的多次调用不会对性能造成影响。

于 2012-06-21T01:17:44.167 回答
1

您是否关心查找有关用户的存储信息?

使用 MVC,您可以随时调用

        User.Identity.Name

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

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

完成基础知识并创建提供程序后,您可以将信息存储到Session成功用户登录时。

于 2012-06-21T01:26:24.473 回答