Безопасность веб-приложений Java: добавление токенов к запросам

Я ищу метод или текущий API, который позволяет добавлять токены в запросы веб-приложений. Может быть, в сеансе, но не сохраняется. Или, если бы вы могли помочь мне, наметив эффективный метод для этого

E.g.

1. GET-запрос => Сервлет генерирует токен и печатает его в представлении

2. возвращает представление со скрытым маркером

<input type="hidden" name="token" value="UA37jdjs9UDJS3">
<input type="submit" name="deleteEmail" value="Delete">

3. Форма запроса POST => отправляется и проверяет, совпадает ли токен.

Несколько вещей, на которые следует обратить внимание: если есть запросы Ajax, то некоторые другие токены должны быть активны для ряда запросов.

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

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

Но как лучше реализовать такую ​​систему,

Есть ли в Spring Security 3 система, которую я могу использовать?

в области Java, Grails, Spring MVC, Spring Security 3 и Hibernate


person Daxon    schedule 07.01.2010    source источник
comment
Я должен спросить - какова цель токенов? Если это якобы для безопасности, то какой цели безопасности они служат? У вас уже есть один уникальный ключ, привязанный к сеансу пользователя (его идентификатор сеанса). В чем преимущество добавления еще одного уникального ключа? Я хочу сказать, что вы думаете, что эти добавленные токены дают вам дополнительный уровень безопасности, но я не совсем уверен, как они это сделают.   -  person delfuego    schedule 07.01.2010
comment
@delfuego - это верно в отношении идентификатора сеанса, но что останавливает любого, кто пытается подделать POST и отправить информацию, мне даже не придется трогать данные, если токен не совпадает или даже не существует,   -  person Daxon    schedule 07.01.2010
comment
Почему они не могли подделать POST с вашим токеном, включенным в их данные POST? Другими словами, идентификатор сеанса и ваш токен являются компонентами одного и того же потока данных — ответа HTTP от сервера, который обслуживает страницу для клиента. Если кто-то может перехватить этот поток, чтобы получить идентификатор сеанса, почему бы ему также не получить токен, а затем использовать их оба?   -  person delfuego    schedule 07.01.2010
comment
Если вы переместите токен на сторону файла cookie, это будет для обработки двойных отправок. Если пользователь попытается пропустить GET и просто перейти к POST, он будет заблокирован, так как в файле cookie нет токена.   -  person Daxon    schedule 07.01.2010


Ответы (5)


Вы ознакомились с разделом «Шаблон маркера синхронизации» в документации по Grails по адресу http://grails.org/doc/1.2.0/guide/single.html ?

person ZbigniewC    schedule 12.01.2010
comment
Я никогда этого не видел, это почти то, что я ищу, я могу узнать, какой метод используется для установки токена в теге формы, посмотреть, могу ли я использовать его самостоятельно для ajax - person Daxon; 12.01.2010

Ознакомьтесь с проектом HDIV на странице http://www.hdiv.org/. Они делают именно это. Даже если вы не используете код проекта HDIV, содержащаяся в нем информация может дать вам возможность сделать это самостоятельно. Для меня это был хороший учебник по работе с токенами для таких вещей, как CSRF, и других применений, таких как элементы управления двойной отправкой.

person Mike    schedule 08.01.2010

Первая мысль заключалась в том, что вы можете просто использовать уже сгенерированный идентификатор сеанса. Но если вы пытаетесь разветвить состояние, я бы предложил использовать что-то вроде создает модель диалога

person Alexander Torstling    schedule 07.01.2010

Почему бы просто не использовать session_id, который веб-контейнер генерирует для вас, когда вы вызываете request.getSession()?

Если вы хотите создать свой собственный «токен», вы можете проверить файлы cookie. Cookie — это пара ключ-значение, отправляемая веб-сервером веб-браузеру в виде HTTP-заголовка, а затем возвращаемая браузером без изменений каждый раз, когда он обращается к этому серверу.

Чтобы создать файл cookie в сервлете, вы можете использовать:

public void doGet ( HttpServletRequest request, HttpServletResponse response )
     throws ServletException, IOException {
  // Create a cookie
  Cookie c1 = new Cookie("yourdomain.token","the value");
  response.addCookie(c1);
 //build your response

}

Файл cookie будет автоматически включен в следующий http-запрос. Вы можете прочитать его обратно с помощью:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
//build your response
}
person Dani Cricco    schedule 07.01.2010
comment
Отслеживание сеанса. Да, это обеспечит довольно большую поддержку, мне просто нужно выяснить методы в Spring Security, если что-то существует, прежде чем я продолжу работу с файлами cookie, спасибо. - person Daxon; 07.01.2010

Недавно я столкнулся с вариантом использования для этого.

Если в браузере присутствовало старое окно приложения, а ссылка для входа была нажата из другого окна браузера, действие входа сначала создавало новый сеанс, а затем перенаправляло в окно приложения. Это активировало метод метода onunload старого окна, что привело к запросу выхода из системы на сервер для выхода нового пользователя из системы.

Полагаться на событие javascript onunload для выхода из системы кажется мне паршивым, но это нельзя было изменить, поэтому мы решили поступить так, как предложил OP, и добавили токен в каждое отображаемое представление, проверяя его для каждого запроса. Это предотвращает завершение нового сеанса запросом на выход из системы onunload.

Что касается лучшего способа, я бы сказал, что это довольно просто. Например, вы можете использовать http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html для создания уникальных ключей. Если вы используете фреймворк на основе компонентов, такой как Tapestry, JSF или Wicket, может быть более высокоуровневый способ справиться с этим.

Это похоже на ваш вариант использования? Или вы пытаетесь достичь чего-то совершенно другого?

person Adriaan Koster    schedule 07.01.2010