JQuery POST, дающий 403 запрещенную ошибку в spring mvc

Я хочу сделать ajax-вызов, используя $.POST. Но я получаю ошибку 403. Но GET работает отлично. Мой код:

var url = "/xyz/abc/subscribe?name="+name;
$.post(url, function(data){
    alert(data);
});

Код контроллера:

@RequestMapping(value = "/xyz/abc/subscribe", method = RequestMethod.POST)
public @ResponseBody
    String subscribe(@RequestParam("name") String name)
        throws Exception {
    String message = "TESTING";
    return message;
}

Но я получаю ошибку 403.

Ответ 1

При использовании Spring Security с настройкой Java защита CSRF включена по умолчанию. В этом контексте, если вы сделаете Ajax-запрос к конечной точке REST с помощью метода POST, вы получите ошибку отсутствия токена csrf.

Чтобы решить эту проблему, есть два варианта:

Вариант 1: отключить csrf

@Override
protected void configure (HttpSecurity http) throws Exception {
    http.csrf().disable();
}

Вариант 2: Добавьте csrf в запрос ajax. Смотрите здесь

Ответ 2

Вам может потребоваться добавить токен csrf в запрос.

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

<script th:inline="javascript">
    /*<![CDATA[*/
    var _csrf_token = /*[[${_csrf.token}]]*/ '';
    var _csrf_param_name = /*[[${_csrf.parameterName}]]*/ '';
    /*]]>*/
</script>

Затем добавьте его в свой запрос:

var requestData = {
    'paramA': paramA,
    'paramB': paramB,
};
requestData[_csrf_param_name] = _csrf_token; // Adds the token

$.ajax({
    type: 'POST',
    url: '...your url...',
    data: requestData,
    ...
});

Если все пойдет хорошо, запрос должен включать что-то вроде _csrf: 1556bced-b323-4a23-ba1d-5d15428d29fa (токен csrf), и вы получите 200 вместо 403.

Ответ 3

Если вы посмотрите на исходный код CSRFilter, вы увидите, что фильтр ждет csrfToken в заголовке или параметре запроса. В моей конфигурации ключ "_csrf" был правильным ключом в параметре запроса. Таким образом, я добавил этот параметр в свой почтовый вызов.

      var csrfCookie = getCsrfCookie();
    		alert(csrfCookie);
    		
    	function getCsrfCookie()
    	{
    		var ret = "";
    		var tab = document.cookie.split(";");
    		
    		if(tab.length>0){
    			var tab1 = tab[0].split("=");
    			if(tab1.length>1)
    			{
    				ret =tab1[1];
    			}
    		}
    		return ret;
    	}
    	
    	$http.post('/testPost?_csrf='+csrfCookie).success(function (response) {
             alert("post : "+response);
              return response;
          });

Ответ 4

Это пример без отключения CSRF.

Шаг 1: Добавьте в свой заголовок CSRF, как это

<meta th:name="${_csrf.parameterName}" th:content="${_csrf.token}"/>

Шаг 2: Сделайте звонок с токеном

$( "#create_something" ).click(function() {

  var token = $("meta[name='_csrf']").attr("content");

  $.ajax({
    url : '/xxxxxxxxxxxx', // url to make request
    headers: {"X-CSRF-TOKEN": token}, //send CSRF token in header
    type : 'POST',
    success : function(result) {
        alert(result);
    }
  })
});

Ответ 5

Вы пытаетесь сделать запрос POST конечной точке REST, на которую вы не авторизованы. Либо ваш сеанс стал недействительным, либо пользователь, с которым вы входите, поскольку у него нет полномочий, таких как @geoand, которые уже указаны.