Я знаю, что этот вопрос задавался много раньше, и он применим много разных способов и основывается на вопросах, которые я уже задал в Интернете, и здесь у меня больше вопросов чем у меня есть ответы.Spring Security 4 curl csrf token не найден
Итак, у меня есть веб-сервис Spring MVC 4.0 RESTful, который, как я знаю, работает нормально. Я знаю, что он работает нормально, потому что он проходит мои модульные тесты. Единичный тест с добавленной безопасностью и «csrf()» как часть безопасности теста заставляет его работать. Я замечаю этот кусок данных добавил:
Parameters = {_csrf=[435f9968-f643-47e9-9d15-23a5cb361b1d]}
RESTful веб-службы обеспечивается с Spring Security 4 и защита CSRF включена по умолчанию. Все веб-сервисы с GET отлично работают, это POST, что мешает мне с этой ошибкой 403.
Вот завиток Я пытаюсь реализовать:
curl \
-d '{"SiteId\:"548","SubjectId":TEST_sub","description":"TEST_des"}' \
--cookie "csrftoken=?????????????" \
--cookie "JSESSIONID=openam~A7FF59011F982FBB91C2F908E143327D" \
--cookie "iPlanetDirectoryPro=AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*; path=/; domain=.mydomain.net" \
-H "X-CSFRToken: ??????" -H "Accept: */*" -H "Content-Type: */*" \
-H "openam-token: AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*" \
https://spring.mydomain.net/api/subject/build
Итак, я знаю, что параметр -d явно делает POST; Я знаю, что --cookie для iPlanetDirectoryPro необходимо для моего приложения. Я знаю, что -H для Accept, Content-Type и openam_token необходимы.
Что меня смущает: -cookie для токена csfr ... откуда я беру эти данные? -cookie для идентификатора сеанса или JSESSIONID? Когда я войти в свой веб-сайт в первый раз, у меня есть печенье, как:
JSESSIONID=openam~A7FF59011F982FBB91C2F908E143327D; path=/sso/; domain=spring-auth.mydomain.net; Secure; HttpOnly
Теперь, когда дело доходит до заголовка: это X-CSFR-токен или X-CSFRToken ... Я видел и то, и другое.
У меня есть SimpleCORSFilter, но этот заголовок не является одним из разрешенных, нужно ли это быть? Я могу добавить его в список приемлемых заголовков.
Меня беспокоит включение _csfr в данные JSON. Если я добавил его с помощью утилиты Jackson, я боюсь, что веб-сервис не будет работать, потому что у _csrf нет соответствующего объекта, поэтому я бы просто предположил, что он будет оттуда, если я это сделаю.
Итак, я сделал много проб и ошибок от завитки, и сегодня мне не очень повезло. Когда я получаю завиток, я должен передать это подрядчику, работающему над пользовательским интерфейсом. Они используют JavaScript для создания AJX-звонков в фоновый сервер, и поэтому они могут передавать все, что им нужно, в URL-адрес, отправлять данные назад, и они могут добавлять любые заголовки или куки-файлы, необходимые для передачи данных. Я оставляю это для них, чтобы понять.
Любая помощь в получении моего завитка для работы будет замечательной. Благодаря!
UPDATE: Когда пользователь входит в мое приложение, мы используем производную от примера SiteMinder. То есть мы получаем cookie из OpenAM, когда мы успешно аутентифицируем. Затем мы используем пример siteminder для вызова CustomUserDetailsService, который использует этот файл cookie для вызова OpenAM и получения имени пользователя. Затем мы выполняем поиск базы данных по этому имени пользователя, чтобы получить роли для этого пользователя. Ни в одном из них мы не получаем какой-либо токен csrf. Итак, для всех примеров, которые я видел в StackOverflow, для меня нет NO csrf token. С этим я добавил следующий веб-сервис RESTful.
@RequestMapping(value = "/csrf-token", method = RequestMethod.GET)
public @ResponseBody String getCsrfToken(HttpServletRequest request)
{
CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
return token.getToken();
}
Я могу позвонить в этот URL в любое время и вернуть маркер обратно клиенту.Например: «45757c25-1af7-40d3-ab8b-1a9cd823efc5»
Итак, я тестирую это в двух местах: RESTClient для Firefox и локон ...
в RESTClient, я могу сделать запрос и получить маркер CSRF, то я пытаюсь поставить его в RESTClient следующим образом:
URL: https://spring.mydomain.net/api/subject/build?_csrf=[45757c25-1af7-40d3-ab8b-1a9cd823efc5]
Headers:
openam_token: AQIC5wM2LY4SfczkVMBTIq4pyjcec7QkyN0PJbY3NdmF8WE.*AAJTSQACMDE.*
X-CSRF-TOKEN: [45757c25-1af7-40d3-ab8b-1a9cd823efc5]
есть ли что-нибудь еще, что мне нужно, потому что он еще не работает.
И локон:
curl \
-d '{"SiteId\:"548","SubjectId":TEST_sub","description":"TEST_des"}' \
--cookie "csrftoken=45757c25-1af7-40d3-ab8b-1a9cd823efc5" \
--cookie "JSESSIONID=openam~A7FF59011F982FBB91C2F908E143327D" \
--cookie "iPlanetDirectoryPro=AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*; path=/; domain=.mydomain.net" \
-H "X-CSFR-TOKEN: 45757c25-1af7-40d3-ab8b-1a9cd823efc5"
-H "Accept: */*" -H "Content-Type: */*" \
-H "openam-token: AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*" \
https://spring.mydomain.net/api/subject/build
Опять же, что я не хватает, чтобы сделать эту работу ????
Должен ли я каким-то образом объединить мой вызов в RESTClient, чтобы получить этот токен, а затем мой POST? Как объединить их в локоть? Я знаю, что на сеанс есть один токен csrf, я хочу знать, что могу сделать один звонок и получить этот токен, а затем использовать его в следующем запросе, чтобы передать обратно POST.
Я не занимаюсь интерфейсом, у нас есть еще одна компания, которая работает над пользовательским интерфейсом и вызовами Ajax, я хочу проверить свой вызов веб-сервиса, прежде чем передавать его вместе с ними.
Еще раз спасибо!
Ошибка 404 после вызова была вызвана тем, что в этом методе метода «build» не было «@ResponseBody», потому что я использовал «@Controller» в этом классе. public MyEntity build («@ RequestBody» SubjectImportDTO subjectImportDTO) должно быть: public «@ResponseBody» MyEntity build («@ RequestBody» SubjectImportDTO subjectImportDTO) ... и это решило эту проблему. – tjholmes66
Typo in curl command: X-CSFR-TOKEN - это cs * RF *, поэтому X-CSRF-TOKEN ... в случае, если кто-то другой скопирует его и задается вопросом, почему он не работает. :) – rudi