使用表单身份验证在 ASP.NET MVC 上的何处存储已记录的用户信息?

发布于 2024-08-13 18:31:33 字数 375 浏览 2 评论 0原文

我在我的应用程序上使用 ASP.NET MVC 和表单身份验证。基本上我使用 FormsAuthentication.SetAuthCookie 登录,使用 FormsAuthentication.SignOut 注销。

在 HttpContext.Current.User.Identity 中,我存储了用户名,但我需要有关已登录用户的更多信息。我不想将整个用户对象存储在会话中,因为它可能很大并且包含比我需要的更多信息。

您认为创建一个名为 LoggedUserInfo 的类(仅包含我需要的属性)然后将其添加到会话变量 中是个好主意吗?这是一个好方法吗?

或者你有更好的想法吗?

I'm using ASP.NET MVC and Forms Authentication on my application. Basically I use FormsAuthentication.SetAuthCookie to login and FormsAuthentication.SignOut to logout.

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.

Do you think it's a good idea to create like a class called LoggedUserInfo with only the attributes I need and then add it to the Session variable? Is this a good approach?

Or do you have better ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

红玫瑰 2024-08-20 18:31:33

我使用这个解决方案:

ASP.NET 2.0 Forms 身份验证 -保持自定义但简单

总结一下:我创建了自己的 IPrincipal 实现。它存储在 HttpContext.Current.Cache 中。如果它以某种方式丢失,我可以从客户端授权 cookie 获得用户名并可以重建它。该解决方案不依赖于会话,会话很容易丢失。

编辑

如果您想在控制器中使用主体并使其可测试,您可以执行以下操作:

    private MyPrincipal _myPrincipal;
    MyPrincipal MyPrincipal
    {
        get
        {
            if (_myPrincipal == null)
                return (MyPrincipal)User;
            return _myPrincipal;
        }
        set
        {
            _myPrincipal = value;
        }
    }

在测试中,您将设置准备测试的对象。否则将从 HttpContext 中获取。现在我开始思考,为什么我要用 Ninject 来做这件事?

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.

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?

回忆追雨的时光 2024-08-20 18:31:33

将其存储在会话的服务器端。

例如。

// 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...
}

然后,当他们登录时,只需执行以下操作来保存用户信息:

// 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" };

然后每当您需要它时就获取它:

UserCredentials user = (UserCredentials)(Session["UserCredentials"]);

我已经编写了一些关于在 MVC 中进行自定义授权的问题/答案:
如何实现授权检查基于会话数据的 ASP.NET MVC?

授权标签如何工作? - Asp.net Mvc

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?

How does the Authorize tag work? - Asp.net Mvc

作死小能手 2024-08-20 18:31:33

我实际上喜欢使用我在登录操作方法中设置的 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");
        }

然后在自定义主体中,您可以使用方法来访问传递给构造函数的特定信息,例如

((CustomIdentity)((CustomPrincipal)HttpContext.Current.User).Identity).DisplayName;

在 CustomIdentity 类中声明 DisplayName 属性的位置。

I actually like to use a CustomPrincipal and CustomIdentity which I set in the logon action method like

        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.

南街九尾狐 2024-08-20 18:31:33

好吧,你必须将这些存储在某个地方。但有两个主要可能的地方:

服务器

您可以将它们放入会话中。我建议您创建一个单独的类,仅保存您实际需要的数据,以避免浪费太多内存。或者,您也可以存储到缓存中,当存在大量并发用户时,最终可能会产生许多数据库调用。

客户端

在这种情况下,如果您可以使用单独的类限制数据量,并使用任何方式对其进行序列化并将其发送到客户端。无论是在 cookie 中还是在 URI 中(如果长度允许并且禁用 cookie)...

这些想法的结果:
如果您通过这种方式获得了很多内存资源,这里的主要内容是创建一个单独的类。所以这是你应该做的第一件事。

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.

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)...

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文