Где хранить зарегистрированную информацию о пользователе на ASP.NET MVC с использованием проверки подлинности с помощью форм? - PullRequest
22 голосов
/ 30 ноября 2009

Я использую ASP.NET MVC и проверку подлинности с помощью форм в своем приложении. В основном я использую FormsAuthentication.SetAuthCookie для входа в систему и FormsAuthentication.SignOut для выхода из системы.

В HttpContext.Current.User.Identity я сохранил имя пользователя, но мне нужно больше информации о зарегистрированном пользователе. Я не хочу хранить весь пользовательский объект в сеансе, потому что он может быть большим и содержать гораздо больше информации, чем мне нужно.

Считаете ли вы хорошей идеей создать как класс с именем LoggedUserInfo только те атрибуты, которые мне нужны, и добавить его в сеанс variable? Это хороший подход?

Или у тебя есть идеи получше?

Ответы [ 4 ]

8 голосов
/ 30 ноября 2009

Я использую это решение:

Аутентификация с помощью ASP.NET 2.0 Forms - возможность сделать ее индивидуальной, но простой

Подводя итог: я создал свою собственную реализацию IPrincipal. Он хранится в HttpContext.Current.Cache. Если это как-то потеряно, у меня есть имя пользователя из файла авторизации на стороне клиента и я могу восстановить его. Это решение не зависит от сеанса, который может быть легко потерян.

EDIT

Если вы хотите использовать своего принципала в контроллере и сделать его тестируемым, вы можете сделать это:

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

В своем тесте вы установите объект, подготовленный для тестирования. В противном случае он будет взят из HttpContext. И теперь я начал думать, почему я использую Ninject, чтобы сделать это?

4 голосов
/ 02 декабря 2009

Мне действительно нравится использовать 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;

где свойство DisplayName объявлено в классе CustomIdentity.

3 голосов
/ 30 ноября 2009

Сохраните его на стороне сервера в сеансе.

Например.

// 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 на основе данных сеанса?

Как работает тег Authorize? - Asp.net Mvc

2 голосов
/ 30 ноября 2009

Ну, вам придется их где-то хранить. Два основных возможных места:

Сервер

Вы можете поместить их в сессию. Я предлагаю вам создать отдельный класс, который будет содержать только те данные, которые вам действительно нужны, чтобы не тратить слишком много памяти. Или же вы можете сохранить в Cache, что может привести к большому количеству вызовов БД при огромном количестве одновременных пользователей.

Клиент

В этом случае, если вы можете ограничить объем данных отдельным классом, использовать этот способ и использовать любой способ для его сериализации и отправки клиенту. В файле cookie или в URI (если длина разрешена, а файлы cookie отключены) ...

Исход этих мыслей:
главное здесь было бы создать отдельный класс, если вы получаете таким образом много ресурсов памяти. Так что это первое, что вы должны сделать.

...