2016-04-20 4 views
2

Я много читал о защите CSRF от Spring Security, но я все еще немного боюсь. Теперь документация отличная, как обычно, но она полностью основана на идее, что вы отображаете html-код на сервере и можете добавлять скрытое поле в каждую форму. Теперь, поскольку я использую AngularJS и JavaScript для вызова бэкэнд, это не вариант.Spring Security CSRF защита REST backend - передача Синхронизатор маркер маркера клиенту

Итак, каков наилучший способ получить токен для клиента в этом случае (Rest Backend/AngularJS frontend)? У AngularJS, похоже, встроена поддержка CSRF в $ resource и ожидается, что Cookie под названием «XSRF-TOKEN» будет загружать токен и отправлять его в виде http-заголовка «X-XSRF-TOKEN» в последующих запросах. Таким образом, каждый запрос будет содержать HTTP-заголовок, а также cookie. Теперь на стороне сервера я мог прочитать заголовок и сравнить его с токеном i, хранящимся в сеансе.

Проблема у меня с этим, это кажется немного сложным. Поскольку сам вход должен быть защищен, ему потребуется создать временную сессию только для токена CSRF. Это действительно необходимо?

Возможно, это всего лишь глупый вопрос, но почему я не могу создать случайный токен на стороне клиента и установить его как HTTP-заголовок и cookie на стороне клиента. Это будет похоже на «OWASP double submit cookie», но сгенерируйте токен на стороне клиента. Таким образом, сервер не будет требовать сеанса перед входом в систему, поскольку он может просто сравнить два представленных токена. Теперь, когда злоумышленник может отправить HTTP-заголовок, он будет придерживаться политики одного и того же происхождения, не имея возможности прочитать или установить файл cookie и не сможет получить соответствие, если это число практически невозможно.

Теперь инстинктивно создавая безопасный токен на стороне клиента, кажется мне опасным, и я думаю, что я избегаю этого ... но ПОЧЕМУ? Я чувствую, что меня что-то пропустили, конечно, есть веская причина, по которой SpringSecurity хранит токен в сеансе, верно?

Пожалуйста, просветите меня :)

+0

[Как получить доступ к веб-сервису Spring CSRF для спокойной работы] (http://stackoverflow.com/questions/33125598/how-to-access-spring-csrf-restful-web-service) может быть полезно? – holmis83

+0

Я уже решил вопрос 2 недели назад, но забыл упомянуть его здесь. Я отправил ответ сейчас. Спасибо хоть! –

ответ

1

Я закончил с использованием spring-security-csrf-token-interceptor-extended, который считывает CSRF-токен из HTTP-заголовка «X-CSRF-токен» (имя настраивается) и отправляет его в качестве HTTP-заголовка в дальнейшие просьбы.

Теперь единственное, что я должен был получить Spring-Security, чтобы отправить токен в качестве заголовка HTTP (так как я не отображаю html-код на сервере и поэтому не могу добавить его как скрытое поле).

<security:http .... 
    <security:custom-filter ref="csrfTokenResponseHeaderBindingFilter" after="CSRF_FILTER"/> 
.... 
</security:http> 

Фильтр в основном выполняется после нормального CSRF_FILTER и читает «_csrf» запрос-атрибута (который ставится там CSRF_FILTER) и устанавливает его в качестве заголовка «X-CSRF-токен»

public class CsrfTokenResponseHeaderBindingFilter extends OncePerRequestFilter { 
    protected static final String REQUEST_ATTRIBUTE_NAME = "_csrf"; 
    protected static final String RESPONSE_TOKEN_NAME = "X-CSRF-TOKEN"; 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException { 
     CsrfToken token = (CsrfToken) request.getAttribute(REQUEST_ATTRIBUTE_NAME); 

     if (token != null) { 
      response.setHeader(RESPONSE_TOKEN_NAME, token.getToken()); 
     } 

     filterChain.doFilter(request, response); 
    } 
} 
Смежные вопросы