Есть ли веская причина, по которой cookie-файлы аутентификации и cookie состояния сеанса являются двумя отдельными cookie-файлами? - PullRequest
2 голосов
/ 20 мая 2011

Есть ли веская причина, по которой cookie-файлы состояния сеанса ASP.NET и cookie-файлы проверки подлинности с помощью форм являются двумя отдельными cookie-файлами?Что если я захочу связать их друг с другом?Это возможно элегантным способом?

Сейчас я застрял со следующим решением, которое работает, но все еще уродливо:

[Authorize]
public ActionResult SomeAction(SomeModel model)
{
    // The following four lines must be included in *every* controller action
    // that requires the user to be authenticated, defeating the purpose of
    // having the Authorize attribute.
    if (SomeStaticClass.WasSessionStateLost/*?*/) {
        FormsAuthentication.SignOut();
        return RedirectToAction("Login", "Account");
    }

    // ...
}

@ RPM1984: Вот что происходит:

[HttpPost]
public ActionResult Login(LoginModel loginModel)
{
    if (/* user ok */)
    {
        // ...
        Session["UserID"] = loginModel.UserID;
        Session["Password"] = loginModel.Password;
        // ...
    }
    else
    {
        return View();
    }
}

И не нужно много догадок, чтобы знать, что делает WasSessionStateLost.

Ответы [ 3 ]

8 голосов
/ 20 мая 2011

Сеанс! = Аутентификация

Файл cookie состояния сеанса отслеживает активность пользователя во время сеанса браузера.

Файл cookie проверки подлинности с помощью форм отслеживает имя пользователя, прошедшее проверку подлинности активность в течение заданного периода времени, указанного датой истечения срока действия билета и того, создали ли вы постоянный файл cookie (например, флажок «Запомнить меня»).

Вы не должны касаться сеансаСам файл cookie, и все, что он содержит, - это идентификатор, связывающий сеанс клиента (браузер) с сервером.

Если вам нужен доступ к сеансу, используйте HttpContext.Current.Session.

Что именноВы пытаетесь «связать» вместе?

Что делает SomeStaticClass.WasSessionStateLost?

2 голосов
/ 20 мая 2011

Я начну с решения, затем объяснения и рекомендации.

Создание пользовательского атрибута авторизации:

Поскольку ваше приложение определяет Authorized следующим образом:

  • Зарегистрировался
  • Должны иметь значения в Session["UserID"] и Session["Password"]

вам нужно определить свой собственный AuthorizationAttribute

    public class AuthorizedWithSessionAttribute : AuthorizeAttribute
    {    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if(httpContext.Request.IsAuthenticated && 
                Session["UserID"] != null && Session["Password"] != null)
                return true;

            // sign them out so they can log back in with the Password
            if(httpContext.Request.IsAuthenticated)
                FormsAuthentication.SignOut(); 

            return false;
        }
    }

Замените все свои атрибуты [Authorize] на [AuthorizedWithSession], и вам не нужно помещать код проверки сеанса в свои контроллеры.

Я недостаточно знаю о вашем приложении, но сохранение паролей в сеансе (что еще хуже в текстовом формате) не является безопасным занятием.

Кроме того, как сказано в RPM1984, cookie сеанса и cookie аутентификации являются отдельными.

Пояснение:

Думайте о сессии как о пакете информации (на стороне сервера) с вашим именем на нем. ASP.NET может взять и положить вещи в это ведро. ASP.NET дает вам имя, идентификатор вашей сессии и помещает его в корзину, чтобы он мог узнать, какая из них ваша.

Файл cookie для аутентификации сообщает ASP.NET, что вы прошли аутентификацию, и сохраняет в нем ваше имя для аутентификации. Имя аутентификации обычно устанавливается разработчиком приложения и обычно является уникальным ключом (например, первичный ключ в БД), чтобы отделить вас от других пользователей.

Рекомендация для большей безопасности:

Зашифруйте пароли перед тем, как хранить их. Это не полная безопасность, но это лучше, чем хранить пароли в виде простого текста, и, конечно, если кто-то получит ключ шифрования, он может взломать пароли.

1 голос
/ 20 мая 2011

Вместо использования сессии, которая недолговечна, вы можете кэшировать ее в System.Web.Cache . При этом вы можете добавить события, которые вызываются до удаления записи, и принять соответствующее решение о необходимости очистки кэша. Вы можете установить более высокое значение тайм-аута с дополнительным бонусом, заключающимся в том, что вы нигде не сохраняете пароль в виде открытого текста в файле или базе данных. Еще один бонус - вы не будете уязвимы для захвата сессии.

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

Хотя это не идеально, записи могут быть сброшены из-за нагрузки на кеш, и, конечно, вы знаете, что это все равно плохая идея, поэтому я пропущу эту лекцию.

...