我是MVC的新手,所以这个问题可能是微不足道的。 在我的LogOn操作中,我执行以下操作:
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;
}
此时我的会话有完整的UserProfile对象,我在网站上使用它,到目前为止工作正常。
下次用户点击网站时,用户已经过身份验证(rememberme设置为true),User.Identity.Name具有之前经过身份验证的用户的电子邮件地址,该地址是正确的。 问题是我想将UserProfile加载到会话中,就像我在LogOn操作中一样。 我想要一个单独的地方,而不是每个[授权]行动。
有这样的方法吗?
答案 0 :(得分: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只是一个包装器,可以更轻松地访问有关经过身份验证的用户的信息。
答案 1 :(得分:1)
更好的方法是实现自定义IIdentity和/或IPrincipal。您可以将常用信息存储在身份验证cookie中。如果信息不敏感(即您只是用它来显示用户名而不用于任何与安全相关的信息),那么您只需将其存储在自己的cookie中即可。
这里有一篇好文章:
http://www.bradygaster.com/custom-authentication-with-mvc-3.0