Подтвердить что ты не робот

Перенаправление на страницу после входа в систему

Я делаю простой форум с серией Servlets, каждый из которых представляет домашнюю страницу, тему, посылку, страницу входа и списка пользователей. На некоторых из этих страниц есть ссылка, которая появляется, когда пользователь не вошел в систему.

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

Первое решение - иметь HTML Form с кнопкой входа и невидимым полем, которое будет содержать информацию, которая скажет, какую страницу перенаправить как Parameter. Это выполнимо, но я хотел бы попробовать что-то еще.

Второе решение - добавить Attribute в session, который каким-то образом представляет первую "страницу". Это может содержать строку, но это ничем не отличается от первого подхода. Другим поворотным моментом было бы добавить ссылку на HttpServlet и использовать instanceof или статическую переменную String, которая может быть использована для идентификации сервлета каким-то образом. Однако для этого потребуется создать общий класс предков для всех Servlets.

Возможно, есть еще одно простое решение, которое вы можете увидеть, что будет хорошим компромиссом? Или, может быть, одно из вышеуказанных решений вполне приемлемо?

4b9b3361

Ответ 1

Я предпочел бы первое выше второго решения. Это запрос с ограниченной информацией и действительно не относится к сеансу, это приведет только к "wtf?". когда у вас открыто несколько окон/вкладок в одном сеансе.

В ссылке на страницу входа просто укажите текущий URL-адрес в качестве параметра запроса:

<a href="/login?from=${pageContext.request.requestURI}">Login</a>

Или, если это форма POST на странице входа в систему:

<input type="hidden" name="from" value="${pageContext.request.requestURI}">

В форме входа передайте его следующему запросу в виде скрытой переменной:

<input type="hidden" name="from" value="${param.from}">

В сервлете входа используйте его:

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession().setAttribute("user", user);
    response.sendRedirect(request.getParameter("from"));
} else {
    // Show error.
}

Довольно просто, не так ли?:)

Некоторые могут предложить использовать request.getHeader("referer") для этого внутри формы входа вместо request.getRequestURI() в ссылке/до входа в систему, но я бы этого не сделал, поскольку это контролируется клиентом и не всегда возвращает надежный Информация. Некоторые клиенты отключили его или используют какое-то программное обеспечение, которое подделывает его с недопустимым значением, например, большинство продуктов (кашля) Symantec.

Ответ 2

Ваш первый предложенный подход является лучшим. У вас есть скрытое поле с value=request.getRequestURI() и перенаправление на этот URI после входа в систему.

Использование referer не будет работать, потому что IE (по крайней мере, некоторые его версии) не устанавливает заголовок referer.

Сохранение параметра в сеансе вызовет странное поведение, если пользователь откроет несколько вкладок.

Изменить: Чтобы лучше проиллюстрировать вопрос:

some resource -> (requests protected resource) -> (gets forwarded to the login page) -> (should be redirected to the original resource)

В большинстве ответов предполагается, что нажата кнопка "Логин" /кнопка, а затем открывается страница входа в систему. Это только одна сторона истории. В этом случае исходный URL ресурса может быть добавлен в качестве параметра и помещен в форму входа (в скрытом поле).

Но в случае пересылки с защищенного ресурса на страницу входа в систему скрытое поле должно содержать URL-адрес прямого запроса.

Это, конечно, не то, что в этом вопросе, но в конечном итоге возникнет как ситуация и должно также рассматриваться.

Ответ 3

Если вы хотите сделать это со страницами, ваша страница входа в систему может посмотреть заголовок referer (sic) в запросе, который его загрузил (request.getHeader("referer")), чтобы увидеть, была ли эта страница на вашем сайте (если нет - или если заголовок отсутствует - используйте по умолчанию какой-либо тип). Затем он сохранит этот URL (я бы, вероятно, использовал скрытое поле, как вы сказали, в форме входа, но также будет работать var var). Когда логин будет завершен, выполните перенаправление на сохраненный URL.

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


Изменить. Еще лучше, как указывает Божо, кодируйте целевую страницу в свою ссылку на страницу входа. Хотя это не так, что IE не устанавливает заголовок "referer" (он делает это), референт не требуется и может быть отключен, и поскольку вы уже динамически создаете страницу, ссылающуюся на форму входа, почему бы если вам не нужно быть.

Ответ 4

от: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity.pdf

глава: Поток приложений при успешном завершении и неудаче аутентификации

... Если аутентификация прошла успешно, результирующий объект аутентификации будет помещен в SecurityContextHolder. Затем настроенный AuthenticationSuccessHandler будет вызван либо для перенаправления, либо для переадресации пользователя в назначенное место назначения. По умолчанию используется SavedRequestAwareAuthenticationSuccessHandler, что означает, что пользователь будет перенаправлен на исходное место назначения, которое они запросили, прежде чем им было предложено войти в систему. ...

Ответ 5

Использование скрытого поля в форме довольно стандартно. Зачем пытаться изобретать колесо?

Ответ 6

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

Параметр может быть отправлен через форму или по ссылке (JSP еще не добавлен):

out.println( "Login <a href='LoginServlet?comeback=home'>here</a><br>" );  

Затем параметр извлекается следующим образом:

String comeback = request.getParameter("comeback");

Как только информация для входа в систему была проверена, перенаправление может быть выполнено следующим образом:

RequestDispatcher rd = request.getRequestDispatcher( redirectionPath );

if( rd != null )
   rd.forward(request, response);