Я знаю, что лучшая практика должна использовать интервал, и весь код MSDN использует интервал Однако нет причины вне стандартизации и непротиворечивости, насколько я знаю.
Я использую это решение:
Аутентификация форм ASP.NET 2.0 - Сохранение настраиваемой, но простой
Подводя итог: я создал свою собственную реализацию IPrincipal . Он хранится в HttpContext.Current.Cache. Если он каким-то образом потерян, у меня есть имя пользователя из файла cookie авторизации на стороне клиента, и я могу его восстановить. Это решение не зависит от сеанса, который можно легко потерять.
РЕДАКТИРОВАТЬ
Если вы хотите использовать свой принципал в своем контроллере и сделать его тестируемым, вы можете сделать это:
private MyPrincipal _myPrincipal;
MyPrincipal MyPrincipal
{
get
{
if (_myPrincipal == null)
return (MyPrincipal)User;
return _myPrincipal;
}
set
{
_myPrincipal = value;
}
}
В своем тесте вы установит объект, подготовленный к тестированию. В противном случае он будет взят из HttpContext. А теперь я задумался, а зачем мне для этого Ninject?
Сохраните его на стороне сервера в сеансе.
Например,
// 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" };
Затем, когда вам это понадобится, получите it:
UserCredentials user = (UserCredentials)(Session["UserCredentials"]);
Я написал пару вопросов / ответов относительно выполнения пользовательской авторизации в MVC: Как реализовать проверки авторизации в ASP.NET MVC на основе данных сеанса?
Что ж, вам придется их где-то хранить. Однако есть два основных возможных места:
Вы можете поместить их в Session. Я предлагаю вам создать отдельный класс, который будет содержать только те данные, которые вам действительно нужны, чтобы не тратить слишком много памяти. Или вы также можете сохранить в кэше, что может привести к множеству вызовов БД при большом количестве одновременных пользователей.
В этом случае, если вы можете ограничить объем данных с помощью отдельного класса, до это и использовать любой способ сериализации и отправки клиенту. Либо в файле cookie, либо в URI (если длина разрешена и файлы cookie отключены) ...
Результат этих мыслей:
Главное здесь - создать отдельный класс, если таким образом вы получите много ресурсов памяти. Итак, это первое, что вам следует сделать.
Мне действительно нравится использовать 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.