2015-08-05 5 views
0

Я создал RestController, который должен помочь управлять тегами в веб-приложении. Я буду называть все методы с помощью AJAX (с помощью JQuery), но результаты по умолчанию безопасности Spring-Boot в следующем (при вызове из Postman):Spring RestController требует CSRF

{ "метки": 1438800538949, "Статус": 403 , «error»: «Forbidden», «message»: «Недопустимый токен CSRF« null »был найден в параметре запроса« _csrf »или заголовке« X-CSRF-TOKEN ».», «путь»: «/ tag/add " }

Каков наилучший способ получить токен CSRF для вызовов JQuery? Я предполагаю, что это лучше, чем отключить его. Как насчет использования PostMan?

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

@RestController 
public class TagController { 

@Autowired 
private TagService tagService; 

@RequestMapping(name = "/tag/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity<TagList> getTagList() { 
    TagList result = new TagList(tagService.list()); 
    return new ResponseEntity<TagList>(result, HttpStatus.OK); 
} 

@RequestMapping(name = "/tag/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity<?> addTag(@RequestBody AlterTagForm form) { 
    try { 
     tagService.addTag(form.getArticleId(), form.getTagName()); 
     return new ResponseEntity<>(HttpStatus.ACCEPTED); 
    } catch (EntityNotFoundException ex) { 
     return new ResponseEntity<>(HttpStatus.NOT_FOUND); 
    } 
} 

@RequestMapping(name = "/tag/remove", produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity<?> removeTag(@RequestBody AlterTagForm form) { 
    try { 
     tagService.removeTag(form.getArticleId(), form.getTagName()); 
     return new ResponseEntity<>(HttpStatus.ACCEPTED); 
    } catch (EntityNotFoundException ex) { 
     return new ResponseEntity<>(HttpStatus.NOT_FOUND); 
    } 
} 
} 
+0

Как это Rest API, вы можете отключить проверку конфигурации csrf. Обычно это выполняется с помощью 'httpSecurity.csrf(). Disable()' в 'WebSecurityConfigurerAdapter .configure()' метод. Также сделайте его безстоящим с помощью 'httpSecurity.sessionManagement(). SessionCreationPolicy (SessionCreationPolicy.STATELESS)'. Поскольку я не смотрю на Spring boot, не знаю, как это делается в нем. –

ответ

0

Во-первых, вам необходимо включить маркер CSRF в вашем HTML:

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

вы можете сделать это в форме тоже, как это:

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

, но я предпочитаю делать это в мета, потому что это в заголовке, и у меня есть это для каждого шаблона с формой (я использую тимелеаф, фрагменты и т. Д.)

Во-вторых, вам нужно изменить свой вызов ajax:

var csrfToken = $('#_csrf').attr("content"); 
var csrfHeader = $('#_csrf_header').attr("content"); 
$.ajax({ 
    url : '/tag/remove', 
    type: 'POST', 
    data: ({ id: id }), 
    beforeSend: function(xhr){ 
      xhr.setRequestHeader(csrfHeader, csrfToken); 
    } 
}).done(function(data, textStatus, jqXHR) { 
     alert('finish'); 
}); 

Установить requestHeader является наиболее важным из этого.

PS: Иногда это может быть случиться так, что csrf header является недействительным для этого вы можете легко заменить это:

var csrfHeader = $('#_csrf_header').attr("content")

с этим:

var csrfHeader = 'X-CSRF-TOKEN';

+0

Значит, я не смогу назвать это webservice-wise, ни через инструмент, как Почтальон? – Kristof

+0

Я не уверен, потому что весенняя безопасность генерирует токен csrf. Я не могу представить, что весна может подтвердить токен от почтальона. я думаю, что вам нужна реализация custome csrf (услуга, в которой весной вы проверяете токен от почтальона) –