ZKOSS - фиксация токена сессии -
Надеюсь, у кого-то есть идея. Что мне нужно:
Проверьте, установлен ли определенный атрибут сеанса при попытке аутентификации:
Sessions.getCurrent().getAttribute(...);
При этом создается новый сеанс. Если атрибут не установлен, проверка подлинности проверяется и должна быть сохранена в новом сеансе. Это должен быть новый сеанс для получения нового идентификатора сеанса, в противном случае приложение будет уязвимо для атак фиксации токена сеанса.
Теперь я не могу сделать сеанс недействительным, получить новый, а затем установить аутентификацию, потому что
Sessions.getCurrent().invalidate();
Sessions.getCurrent(true).setAttribute(...);
не будет уничтожать сеанс до тех пор, пока последний запрос не будет завершен, поэтому getCurrent() здесь выдаст мне "старый" сеанс, который на данный момент все еще действителен.
Моя идея заключалась в том, чтобы впоследствии отправить пересылку с необходимыми атрибутами в URL-адресе, чтобы сохранить их в другом методе для сеанса, в котором у меня будет доступ к новому сеансу. Тем не менее, я получаю IllegalStateException:
java.lang.IllegalStateException: используйте sendRedirect вместо этого при обработке запроса пользователя
Есть идеи, как решить этот сценарий?
Заранее спасибо! MJ.
1 ответ
Я не эксперт по безопасности, поэтому, пожалуйста, проверьте сами (и вместе с вашей командой безопасности), соответствует ли приведенный ниже код вашим конкретным требованиям. Он просто пытается продемонстрировать, как собственные объекты сеанса и запроса могут использоваться для условного аннулирования сеанса, установки / проверки атрибута и пересылки запроса, если это необходимо.
Для этого сценария я бы предложил более низкий уровень абстракции и напрямую работал с нативными объектами HttpSession и HttpServletRequest, например, в фильтре сервлета.
Это отлавливает потенциальные попытки манипулирования на более ранней стадии обработки запроса (и делает вас независимым от используемой структуры фрейма).
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class CheckCertainAttributeFilter implements Filter {
public static final String CERTAIN_SESSION_ATTRIBUTE = "certain-session-attribute";
public static final String MY_EXPECTED_VALUE = "my-expected-value";
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final HttpSession session = httpServletRequest.getSession();
//session present, check for certain session attribute value
if (session != null) {
final String certainSessionAttributeValue =
(String) session.getAttribute(CERTAIN_SESSION_ATTRIBUTE);
if (!MY_EXPECTED_VALUE.equals(certainSessionAttributeValue)) {
session.invalidate();
HttpSession newSession = ((HttpServletRequest) request).getSession(true);
newSession.setAttribute(CERTAIN_SESSION_ATTRIBUTE, MY_EXPECTED_VALUE);
request.getRequestDispatcher("/login.zul").forward(request, response);
}
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void destroy() { }
}
Затем настройте фильтр в своем файле web.xml.
<filter>
<filter-name>checkCertainAttribute</filter-name>
<filter-class>CheckCertainAttributeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>checkCertainAttribute</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
После этого каждый запрос будет перенаправлен на страницу login.zul, если в атрибуте сеанса нет ожидаемого значения.