Фиксация сессии в ASP.Net MVC - PullRequest
       12

Фиксация сессии в ASP.Net MVC

1 голос
/ 02 ноября 2009

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

Допустим, есть два маршрута: Index и Index2 из HomeController.

www.website.com/home вызовет выполнение Index, затем я хочу выполнить некоторый код и затем перенаправить (или перенести на сервер) на www.website.com/home/index2.

Я не хочу, чтобы URL www.website.com/home/index2 был доступен непосредственно пользователю, не заходя сначала на home/index.

Что я могу сделать, чтобы деактивировать / активировать маршрут во время выполнения?

РЕДАКТИРОВАТЬ: Извините, этот вопрос называется «Фиксация сессии», потому что мне нужно, чтобы Index запустился до Index2, чтобы убедиться, что мы убиваем все сессии в Index и обновляем их до выполнения Index2.

Я не могу завершить сеанс и выполнить код в Index2 в том же запросе, поскольку Index2 нужен сеанс для выполнения своей работы.

Ответы [ 5 ]

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

Нет, если вы делаете перенаправление. Если вы сделаете редирект, он будет отображаться на контроллере так же, как если бы запрос просто исходил из браузера (что он и делает). Вы можете создать что-нибудь с помощью TempData - то есть установить там флаг и выполнить действие только в том случае, если флаг находится в TempData - но если это не следующий запрос от браузера, он потерпит неудачу. То есть вы можете получить еще один запрос, скажем, через AJAX, который находится между оригиналом и перенаправлением. TempData будет уничтожен этим запросом.

Если, с другой стороны, вы просто хотите выполнить код, не открывайте Index2 как открытый метод и не вызывайте его напрямую. Если он находится в одном контроллере, это должно сработать. Вы получите тот же URL-адрес, но если он просто получает правильное представление, которое вы хотите, все будет в порядке.

1 голос
/ 05 ноября 2009

ОК, это то, что мы в итоге сделали. Кто-нибудь видит какие-либо предостережения при таком подходе?

Index()
{
    expire all session and forms-Authententication cookies
}

Index2()
{
   if(Session.IsNewSession)
   {
      redirect to Index action
   } 
   else
   {
     Show view
   }
}
1 голос
/ 03 ноября 2009

Вы можете установить ActionFilter и выполнить очистку сеанса / и т.д. Таким образом, ваш код всегда будет выполняться перед Index2 - и перед любым действием, для которого вы установите этот атрибут.

public class AbandonSessionAttribute: ActionFilterAttribute
{
   public void OnActionExecuting(ActionFilterContext context)
   {
      if (Session.User.IsAuthenticated || Session.Count > 0)   // <<-- this is the important line
      {
         Session.Clear();
         FormsAuthentication.SignOut(); // and so on
         context.Result = new RedirectResult("/Index2");
      }
   }
}

// now, if this is called with non-empty session, it will be cleared and user will be redirected again here
[AbandonSession]
public ActionResult Index2()
{
}

Обратите внимание на "это важная строка". Там вам нужно определить, разрешено ли пользователю входить в Index2. Я делаю это, проверяя, что Сессия не пуста. Тем не менее, после перенаправления MVC может добавить свои собственные переменные Session, так что Session никогда не будет пустым, и фильтр будет перенаправлять снова и снова ... Вам нужно будет выяснить, что нормально для представления в Session. Из вашего вопроса неясно (для меня), если ЛЮБОЙ переход к Index2 должен очистить сеанс - т.е. во время просмотра сайта. Если это так, приведенный выше код в порядке, если нет - вам решать, как это обнаружить (например, поместить что-либо в сеанс на некоторых страницах и удалить оттуда на других).

Опять же, я не понимаю, почему Session не будет работать для вас (и, кстати, TempData также работает через Session). Если фильтр действий, который вы обнаруживаете, этот запрос не является «чистым» - есть вход в систему, сеансовые переменные и т. Д. - вы очищаете это и перенаправляете еще раз к тому же действию - это вызывает создание нового сеанса и так на. На этот раз фильтр ничего не находит - поскольку сессия только что была очищена - и поэтому разрешено выполнение действия.

1 голос
/ 02 ноября 2009

Если пользователь перенаправлен на сайт www.website.com/home/index2, он должен сделать запрос в браузере, даже если это происходит автоматически от его имени. Единственный способ предотвратить это - выполнить проверку действия Index2, проверяющего HTTP Referer.

Другим вариантом было бы, чтобы Index возвращал ActionResult из Index2, таким образом, URL остается в / home / index, но результаты Index2 возвращаются, и, насколько пользователь обеспокоен, они никогда не были перенаправлены.

0 голосов
/ 02 ноября 2009

Вы можете определить маршрутизацию:

routes.MapRoute(
            "Index2Redirect",
            "HomeController/Index2",
            new { controller = "HomeController", action = "Index", id = "" }
        );

EDIT:

Нет, это не хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...