2011-05-05 24 views
1
var query = from p in AdminModelContext.Users 
      where p.UserName == model.UserName && p.Password == encryptPassword 
      && p.IsDeleted == false 
           select p; 
      IList<Users> userList = query.ToList(); 

if (userList.Count() > 0) 
{ 
    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 

    if (CheckUrl(returnUrl)) 
    { 
     return Redirect(returnUrl); 
    } 

    SetRoleForUser(userList[0].RolesId); 
    LoggerService.Info(string.Format("Login Successful for the user : {0}", 
     model.UserName)); 

    return RedirectToAction("Index", "Home"); 
} 

我使用下面的代码通过我的网站登录。我面临的问题是当我在特定的浏览器上登录用户,并同时在不同的浏览器上用不同的用户登录,然后删除用户(在其他浏览器上登录)。我仍然可以浏览已删除的用户登录的页面。已删除用户登录后,即使删除另一个大衣

我没有找到一个公平的解决方案,将认证逻辑放在每一页上。我的网站采用MVC模式,并使用基于表单的身份验证。

请建议我怎么能把登录的用户会话验证,并实现这一点。

+0

上面的代码是正确的,你的问题是与身份验证票证,它仍然是在用户计算机上的有效,所以这段代码没有得到执行。我会建议,检查Global.asax,Session_Start事件上的用户删除状态。 – hazimdikenli 2011-05-05 14:04:49

+0

如果使用被删除,那么你只需要FormsAuthentication.SignOut(或类似的东西,然后Session.Abandon) – hazimdikenli 2011-05-05 14:05:57

+0

好吧,看来你的问题并不那么简单,我为它添加了一个答案。 – hazimdikenli 2011-05-05 14:36:37

回答

0

通常情况下,如果您为控制器或操作定义[Authorize]属性,则会在每个回发中检查身份验证。

MembershipProvider中的构建可以处理所有这些。但似乎你正在使用你自己的用户数据库。然后你必须实现你自己的MembershipProvider,IPrincipalMembershipUser,并将其添加到你的Web.config中,替换默认的。

更多,你会发现这里如何实现自己的MembershipProvider:http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx

我的建议是创建一个空MVC项目,看看默认的身份验证机制。如果您使用新数据库构建新应用程序,请尝试使用默认身份验证。

您自己的MembershipProvider中的validateUser函数可能如下所示。

public override bool ValidateUser(string username, string password) 
{ 
    bool isValid = false; 
    bool isApproved = false; 
    string pwd = ""; 

    using (AdminModelContext db = new AdminModelContext()) 
    { 
     var user = db.Users.FirstOrDefault(u => u.UserName == username); 
     if (user != null) 
     { 
      pwd = user.Password; 
      isApproved = user.IsApproved; 

      if (CheckPassword(password, pwd)) 
      { 
       if (isApproved) 
       { 
        isValid = true; 

        user.LastLoginDate = DateTime.Now; 
        user.LastActivityDate = DateTime.Now; 

        try 
        { 
         db.SubmitChanges(); 
        } 
        catch (Exception ex) 
        { 
         Console.WriteLine(ex); 
        } 
       } 
      } 
      else 
      { 
       UpdateFailureCount(username, "password"); 
      } 
     } 
    } 

    return isValid; 
} 
+0

我最初的反应就是出于DV的原因与来自@Sergi Papseit的回答相同,但我并不确定会员提供商不会做类似于我在回答中所说的内容。我从不使用它们,删除它们始终是我创建项目的第一步。 – 2011-05-05 13:47:00

+0

我当然希望user.Password是一种单向散列值。过去,如果这是对每个请求的触发,我真的不得不相信这会推翻任何中等并发使用率的数据库。 – 2011-05-05 13:52:53

+0

MembershipProvider和AuthorizeAttribute完美地一起工作。使用AuthorizeAttribute标记控制器,所有操作只能由授权用户访问。如果Mvc检测到需要授权的Controller或Action,则会调用MembershipProvider.ValidateUser()。如果这个用户不存在,它将返回false。 – DanielB 2011-05-05 13:59:31

1

到目前为止,没有任何答案能够真正确认问题。

让我们看看控制流:

User A enters log in page, supplies valid credentials 
User A is issued Ticket A. 

User B enters site, supplies valid credentials. 
User B is issued Ticket B. 

User B then revokes User A's access CREDENTIALS. 

在这一点上没有任何反应票务A.因为机票是独立的凭证。当机票A到期时,他们将被要求出示他们的凭证,并且将无法登录。

所以你已经注意到,踢出你的网站的活用户实际上很难。正如您已经意识到唯一的解决方案是在每个请求上都有验证逻辑。那不幸的是真的很重。

在我建立的登录系统中,我通过创建2张票据,1张存储在持续时间较长的正常表单身份验证票证中的票证和一张存储在HttpRuntime.Cache中的票证来处理此方面,我将缓存过期设置为这张票15分钟。

在每个页面请求上,我检查用户是否在缓存中有一张票(基于他们的Forms Auth票据信息),此时如果他们没有票据我做用户数据刷新并轮询用户数据库。如果用户被暂停或删除,他们将在当时被注销。

使用这种方法,我知道我的网站可以禁用用户,并在15分钟内,用户将被禁止从网站。如果我希望他们立即禁止我可以循环应用程序配置清除缓存并强制它发生。

+0

这不是问题所在。问题是,如果有另一个会话从同一个用户打开,即使他登出其中一个会话,剩下的会话仍然能够浏览需要登录的页面,而它是同一个用户,他应该已从其他会话中注销。 – 2011-05-05 13:56:21

+1

我已阅读了5次这个问题,并且我每次都错过了“不同用户”的“*不同*”一词=( – 2011-05-05 14:00:48

+1

无论您是否使用2门票系统,如果意图是为了确保用户在删除用户后无法访问项目,那么您需要适当的授权代码,以确认即使表单身份验证声明用户已通过身份验证,但他们无权查看内容。谨慎处理任何错误/过时的身份验证应显示的问题 – KallDrexx 2011-05-05 14:30:07

0

我现在看到问题了。我不知道这是如何在MVC中工作的,但通过使用Authenticate_Request,您可以验证用户是否仍然有效。业务逻辑还可以仔细检查用户是否仍然有效。但据我所知,无法迭代所有打开的会话并杀死重要的会话,即使在这种情况下,应该在Session_Start事件上重复检查授权cookie。 另一种选择是在应用程序中添加一个全局invalidated_users列表,然后检查该用户与无效列表。该列表应该只包含在应用程序重新启动后失效的用户。

链接,阅读所有用户会话:

http://weblogs.asp.net/imranbaloch/archive/2010/04/05/reading-all-users-session.aspx