2012-10-23 89 views
2

我是MVC的新手,所以这个问题可能是微不足道的。 在了登录的动作,我执行以下操作:新手:MVC3身份验证/记住我

public ActionResult LogOn(UserModel userModel, string returnUrl) 
    { 
     ActionResult retvalue = null; 
     UserProfile user = MyDatabaseAccess.Instance.GetAuthenticatedUser(userModel.EmailAddress, userModel.Password); 
     if (user != null) 
     { 
      FormsAuthentication.SetAuthCookie(userModel.EmailAddress, userModel.RememberMe); 
      Session["LoggedOnUser"] = user; 
      if (Url.IsLocalUrl(returnUrl)) 
      { 
       retvalue = Redirect(returnUrl); 
      } 
      else 
      { 
       retvalue = RedirectToAction("Home", "Home"); 
      } 
     } 
     else 
     { 
      retvalue = RedirectToAction("LogOn", "Account"); 
     } 
     return retvalue; 
    } 

在这一点上我的会议有充分的用户配置对象,我用它throught的网站,到目前为止一切正确运转。

用户下次访问该网站时用户已经通过身份验证(rememberme设置为true),并且User.Identity.Name具有之前通过验证的用户的电子邮件地址,该地址是正确的。 问题是,我想以与在LogOn操作中一样的方式将UserProfile加载到会话中。 我想要一个地方,而不是每个[授权]行动。

有没有这样的方法?

+0

这不是存储在会话中的信息是个好主意。原因是会话cookie比认证cookie脆弱得多。会议也有像你遇到的问题。另外请记住,一个会话可以随时消失。它可以过期,或工作进程可以回收,或者其他几个原因,但最终的结果是会话将会消失在你身上。 Plus会话更难以扩展到服务器场方法。在那里存储任何状态并不是一个好主意,如果你这样做,应该是短期的。 –

回答

2

这样做的一种方法是创建一个SecurityContext,通过它可以访问用户信息。然后,您可以在会话中保留您的SecurityContext。如果用户通过身份验证,但会话中不存在SecurityContext,则您从Db读取数据并将其重新添加到会话中。

像这样的东西可能:

public static class SecurityContext 
{ 
    public static UserProfile CurrentUser 
    { 
     get 
     { 
      var user = HttpContext.Current.Session["CurrentUser"] as UserProfile; 

      if (user == null) 
      { 
       using (var ctx = new YourDbContext()) 
       { 
        user = ctx.User.SingleOrDefault(u => u.UserName == 
           HttpContext.Current.User.Identity.Name); 
        HttpContext.Current.Session["CurrentUser"] = user; 
       } 
      } 

      return user; 
     } 
     set 
     { 
      HttpContext.Current.Session["CurrentUser"] = value; 
     } 
    } 
} 

在应用程序中的任何时候,你可以再通过调用SecurityContext.CurrentUser

你当然会访问用户的个人资料仍然必须使用[Authorized]属性控制器上/操作来确保用户已通过身份验证。 SecurityContext只是一个包装器,可以更容易地访问有关经过身份验证的用户的信息。

+0

您能否详细说明一个例子或文章? – Pacman

+0

这是一种常见的方式,但我认为这是一种严重的黑客行为。更好的解决方案是定制IIdentity和IPrincipal。 –

+0

@Christofer Eliasson:那时我没有访问User.Identity的权限,除非它在我的一个Actions中。你怎么回事? – Pacman

1

更好的方法是通过实现自定义IIdentity和/或IPrincipal。您将经常使用的信息存储在Authentication cookie中。如果信息不敏感(即,您只是使用它来显示用户名称,而不是用于与安全相关的任何内容),那么您可以将其存储在您自己的Cookie中。

有一个很好的文章在这里:

http://www.bradygaster.com/custom-authentication-with-mvc-3.0