Spring Rest Service - недействительный токен CSRF при попытке входа в систему

У меня есть служба Spring MVC REST с включенной Spring Security (3.2.5.RELEASE). Когда я включаю @EnableWebMvcSecurity, для меня автоматически создается форма входа по адресу http://localhost:8080/login. Если я использую эту форму для входа в систему, все работает нормально.

Проблема возникает, когда я пытаюсь войти, отправив запрос POST напрямую. В своем почтовом запросе я указываю имя пользователя и пароль. Я также включаю http-заголовок «X-CSRF-TOKEN», а для значения заголовка я использую JSESSIONID, который, как я вижу, был сгенерирован в файле cookie. Но когда я отправляю этот запрос POST, я получаю следующий результат:

HTTP Status 403 - Invalid CSRF Token '29F5E49EFE8D758D4903C0491D56433E' 
was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

Что я делаю неправильно? Я указываю неверное значение токена? Что это за JSESSIONID? Если я не ввожу значение для этого заголовка или опускаю заголовок целиком, он сообщает мне «Обнаружен нулевой токен CSRF».

Ниже представлена ​​моя конфигурация Spring Security:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/secure/**").authenticated()
                .and()
            .formLogin()
                .usernameParameter("username")
                .passwordParameter("password")        
                .and()
            .logout()
                .and()
            .httpBasic()
                .and()
            .csrf(); 
    }
}

Буду очень признателен за любую помощь! Заранее спасибо!


person AlexG    schedule 25.02.2015    source источник
comment
При более внимательном рассмотрении HTTP-запроса / ответа, когда я использую форму входа, выясняется, что JSESSIONID не является значением, которое я должен предоставить для заголовка X-CSRF-TOKEN. Когда я вхожу в систему с помощью формы, я вижу, что в запрос включен токен CSRF. Как мне получить это значение, если мне нужно было войти в систему с помощью вызовов службы REST?   -  person AlexG    schedule 26.02.2015
comment
Это значение можно получить, выполнив сначала вызов GET, а затем POST.   -  person java_dude    schedule 26.02.2015


Ответы (3)


(1) Включите токен CSRF во все ваши запросы AJAX.

$(function () {
    var token = $('#logoutform>input').val();
    var header = $('#logoutform>input').attr('name');
    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader('X-CSRF-TOKEN', token);
    });
 });

(2) Простой запрос.

<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
person Parth Solanki    schedule 04.04.2015

Вам необходимо отправить токен csrf при отправке формы входа. Добавьте следующую строку в HTML-форму:

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
person Mithun    schedule 26.02.2015

вам нужен <meta name="_csrf" content="${_csrf.token}"/>, https://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection/#ajax-requests

или если вы используете тимелеф <meta name="_csrf" th:content="${_csrf.token}" />

person mariubog    schedule 04.04.2015