Как настроить Spring Security для отправки 'X-CSRF-TOKEN'?

Проблема в том, чтобы токены CSRF работали между Spring Security и Angular.

Spring Security CSRF Token Interceptor для Angular выглядит как нечто, что должно делать эту работу, но в ответе HEAD от сервера нет 'X-CSRF-TOKEN'.

Моя текущая крошечная реализация доступна в GitHub (Tag v.1.0) и я был бы очень признателен, если бы кто-то, кто знает эту тему, быстро взглянул на код, проблему легко заметить.

Исходя из документации, у меня сложилось впечатление, что CSRF должен был быть включен автоматически, но, похоже, это не так.

Я использую Spring Boot и предпочитаю конфигурацию на основе аннотаций XML, если что-то нужно настроить по-другому.

Есть ли другие способы заставить Spring Security работать против Angular?

2 ответа

Решение

Я считаю, что Angular ищет файл cookie под названием "XSRF-TOKEN", поэтому для клиента проще всего отправить его. Вы можете сделать это в Filter например (пример с https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/single/src/main/java/demo/UiApplication.java#L65):

    private Filter csrfHeaderFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                        .getName());
                if (csrf != null) {
                    Cookie cookie = new Cookie("XSRF-TOKEN", csrf.getToken());
                    cookie.setPath("/");
                    response.addCookie(cookie);
                }
                filterChain.doFilter(request, response);
            }
        };
    }

Обновление: начиная с весны безопасности 4.2 правильное имя cookie для angular используется по умолчанию, если вы используете репозиторий cookie csrf (ссылка по-прежнему лучший источник), то есть больше нет необходимости в настраиваемом фильтре. Пример:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                ...
                .and()
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

Я отвечаю на вопрос сам, так как в исходном репозитории GitHub был скрытый: выпуск № 1.

Решением было добавить пару строк Java-кода, который добавляет параметры CSRF в качестве заголовков сообщений Http.

Я добавил рабочее решение в репозиторий GitHub с тегом v.2.0,

Другие вопросы по тегам