Redmine / Java native: обновление запроса по сценарию. Запрос клона Fiddler - PullRequest
0 голосов
/ 01 ноября 2018

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

Я пытаюсь повторить тот же запрос, который я тестирую на Fiddler, чтобы он работал, следующим образом:

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
String host = 'redmine.our-domain.com';
String url = 'http://redmine.our-domain.com/queries/4088';
String REDMINE_SESSION_COOKIE = "_redmine_session=BAh7DkkiDHVzZXJfaWQGOgZFRmkvSSIKY3RpbWUGOwBGbCsHmouFWkkiCmF0aW1lBjsARmwrByk211tJIg9zZXNzaW9uX2lkBjsARkkiJTMzZWJkNmI1MzA4MzZkNmMxNGYwNjY1OWQxMDZjZmU3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMVB3bDlCb0F5NFFCbTd3dmdGWGx0VjdEL05WYjhVRGExdFluQmNMbnFZTHM9BjsARkkiCnF1ZXJ5BjsARnsHOgdpZGkC%2BA86D3Byb2plY3RfaWRpAssBSSIWaXNzdWVzX2luZGV4X3NvcnQGOwBGSSIMaWQ6ZGVzYwY7AEZJIg1wZXJfcGFnZQY7AEZpaUkiFWZqbGVzX2luWGV4X3NvcnQGOwBGSSINZm2sZW5hbWUGOwBG--5c961485290b3c98f38de934b939d25cc01e092f"
String data = "_method=put&authenticity_token=Pwl9BoAy4QBm7wvgFXlsV7D%2FNVb8UDa2tYnBcLnqYLs%3D&query%5Bname%5D=Current+sprint+1.75-test+API+0+0+1&query%5Bvisibility%5D=2query%5Bgroup_by%5D=category&f%5B%5D=status_id&op%5Bstatus_id%5D=o&f%5B%5D6=fixed_version_id&v%5Bfixed_version_id%5D%5B%5D=6030&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=fixed_version&c%5B%5D=start_date&c%5B%5D=due_date&c%5B%5D=estimated_hours&c%5B%5D=done_ratio&c%5B%5D=parent";
byte[] body = data.getBytes("UTF-8");

HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
http.setRequestMethod('POST');
http.setRequestProperty('Cookie', REDMINE_SESSION_COOKIE);
http.setRequestProperty('Content-Type', 'application/x-www-form-urlencoded');
http.setRequestProperty('Host', host);
http.setRequestProperty('Content-Length', "${body.length}");
http.setDoOutput(true);
http.getOutputStream().write(body);

Оба, data authenticity_token и сессионный cookie - это подделка, но я копирую Fiddler. Я добавляю Host и Content-Length, потому что Fiddler всегда добавляет их.

Fiddler возвращает статус 302, что он прав, потому что Redmine перенаправляет страницу. С кодом выше я получаю статус 422 (Unprocessable Entity) с этим сообщением в теле: Неверный токен подлинности формы

Я потратил 3 дня, пытаясь выяснить, что я делаю неправильно, чтобы клонировать запрос. Любая подсказка?

1 Ответ

0 голосов
/ 05 ноября 2018

Вы должны вместо этого попытаться использовать API Redmine для достижения своей цели, вместо того, чтобы пытаться отправлять данные html-формы в контроллер.

Форма входа Redmine создает также невидимые поля данных формы, которые вы можете видеть при просмотре в своем браузере (обычно F12).

Одним из таких скрытых полей является маркер подлинности, и он генерируется новым, каждый раз при визуализации формы.

enter image description here

Fiddler, вероятно, работает, потому что он выполняет базовую аутентификацию, как описано здесь: http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication

Таким образом, в вашем коде вы должны удалить часть кода, пытаясь имитировать данные формы, и вместо этого использовать обычную аутентификацию, например:

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
String host = 'redmine.our-domain.com';
String url = 'http://redmine.our-domain.com/queries/4088';
String auth = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));  //Java 8 - not sure for 7

HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
http.setRequestProperty("Authorization", "Basic "+auth);    
http.setRequestMethod('POST');
http.setRequestProperty('Cookie', REDMINE_SESSION_COOKIE);
http.setRequestProperty('Content-Type', 'application/x-www-form-urlencoded');
http.setRequestProperty('Host', host);
http.setRequestProperty('Content-Length', "${body.length}");
http.setDoOutput(true);
http.getOutputStream().write(body);
...