asp.net-mvc 使用表单身份验证在 ASP.NET MVC 上存储记录的用户信息的位置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1821412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Where to store logged user information on ASP.NET MVC using Forms Authentication?
提问by Guillermo Guerini
I'm using ASP.NET MVC and Forms Authentication on my application. Basically I use FormsAuthentication.SetAuthCookieto login and FormsAuthentication.SignOutto logout.
我在我的应用程序上使用 ASP.NET MVC 和表单身份验证。基本上我 FormsAuthentication.SetAuthCookie用来登录和FormsAuthentication.SignOut注销。
In the HttpContext.Current.User.Identity I have stored the user name but I need more info about the logged user. I don't want to store my entire User obj in the Session because it might be big and with much more infomation than I need.
在 HttpContext.Current.User.Identity 中,我存储了用户名,但我需要有关登录用户的更多信息。我不想将我的整个 User obj 存储在 Session 中,因为它可能很大并且包含比我需要的更多的信息。
Do you think it's a good idea to create like a class called LoggedUserInfowith only the attributes I need and then add it to the Session variable? Is this a good approach?
您认为创建一个LoggedUserInfo仅使用我需要的属性调用的类然后将其添加到 Session是个好主意variable吗?这是一个好方法吗?
Or do you have better ideas?
或者你有更好的想法?
回答by LukLed
I use this solution:
我使用这个解决方案:
ASP.NET 2.0 Forms authentication - Keeping it customized yet simple
To summarize: I created my own IPrincipal implementation. It is stored in HttpContext.Current.Cache. If it is somehow lost, I have username from client side authorization cookie and can rebuild it. This solution doesn't rely on Session, which can be easily lost.
总结一下:我创建了自己的 IPrincipal 实现。它存储在 HttpContext.Current.Cache 中。如果不知何故丢失了,我从客户端授权 cookie 中获得用户名,并且可以重建它。此解决方案不依赖 Session,它很容易丢失。
EDIT
编辑
If you want to use your principal in your controller and make it testable, you can do this:
如果你想在你的控制器中使用你的主体并使其可测试,你可以这样做:
private MyPrincipal _myPrincipal;
MyPrincipal MyPrincipal
{
get
{
if (_myPrincipal == null)
return (MyPrincipal)User;
return _myPrincipal;
}
set
{
_myPrincipal = value;
}
}
In your test, you will set object prepared for testing. Otherwise it will be taken from HttpContext. And now I started thinking, why do I use Ninject to do it?
在您的测试中,您将设置为测试准备的对象。否则它将从 HttpContext 中获取。现在我开始思考,为什么我要用 Ninject 来做这件事?
回答by user205258
I actually like to use a CustomPrincipal and CustomIdentity which I set in the logon action method like
我实际上喜欢使用我在登录操作方法中设置的 CustomPrincipal 和 CustomIdentity,例如
if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password) && _authService.IsValidLogin(username, password))
{
User objUser = _userService.GetUserByName(username);
if (objUser != null)
{
//** Construct the userdata string
string userData = objUser.RoleName + "|" + objUser.DistrictID + "|" + objUser.DistrictName + "|" + objUser.ID + "|" + objUser.DisplayName;
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(username, rememberMe.GetValueOrDefault());
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userData);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
Response.Cookies.Add(authCookie);
return RedirectToAction("Index", "Absence");
}
else
{
return RedirectToAction("LogOn", "Account");
}
}
else
{
return RedirectToAction("LogOn", "Account");
}
Then in the custom principal you can have methods that access specific information you passed in to the constructor like
然后在自定义主体中,您可以拥有访问您传递给构造函数的特定信息的方法,例如
((CustomIdentity)((CustomPrincipal)HttpContext.Current.User).Identity).DisplayName;
where the DisplayName property is declared in the CustomIdentity class.
其中 DisplayName 属性在 CustomIdentity 类中声明。
回答by Kelsey
Store it server side in the session.
将其存储在会话中的服务器端。
Eg.
例如。
// Make this as light as possible and store only what you need
public class UserCedentials
{
public string Username { get; set; }
public string SomeOtherInfo { get; set; }
// etc...
}
Then when they sign in just do the following to save the users info:
然后,当他们登录时,只需执行以下操作即可保存用户信息:
// Should make typesafe accessors for your session objects but you will
// get the point from this example
Session["UserCredentials"] = new UserCredentials()
{ Username = "SomeUserName", SomeOtherInfo = "SomeMoreData" };
Then whenever you need it fetch it:
然后每当你需要它时获取它:
UserCredentials user = (UserCredentials)(Session["UserCredentials"]);
I have written a couple of question/answers regarding doing custom authorization in MVC: How to implement authorization checks in ASP.NET MVC based on Session data?
我写了几个关于在 MVC 中进行自定义授权的问题/答案: How to implement authorization checks in ASP.NET MVC based on Session data?
回答by Robert Koritnik
Well you will have to store these somewhere. Two main possible places though:
那么你将不得不将这些存储在某个地方。两个主要可能的地方:
The server
服务器
You can either put them into Session. I suggest you do create a separate class that will hold only data that you actually need to avoid of wasting too much memory. Or you can also store into Cache that can end up in having many DB calls when there are huge amounts of concurrent users.
您可以将它们放入会话中。我建议您创建一个单独的类,该类只保存您实际需要的数据,以避免浪费太多内存。或者您也可以存储到 Cache 中,当有大量并发用户时,它可能会导致许多 DB 调用。
The client
客户端
In this case if you can limit the amount of data with a separate class, to that and use whatever way to serialize it and send it to the client. Either in a cookie or in URI (if length permits and cookies are disabled)...
在这种情况下,如果您可以使用单独的类来限制数据量,并使用任何方式对其进行序列化并将其发送给客户端。在 cookie 或 URI 中(如果长度允许且 cookie 被禁用)...
Outcome of these thoughts:
the main thing here would be to create a separate class if you gain much memory resources this way. So that's the first thing you should do.
这些想法的结果:
如果您以这种方式获得大量内存资源,这里的主要事情是创建一个单独的类。所以这是你应该做的第一件事。

