Как диагностировать бесконечный цикл перенаправления

#servicestack

#servicestack

Вопрос:

Нам пришлось понизить версию servicestack с бесплатной версии 5.4 до платной версии 4.5.14. Единственным изменением, необходимым для компиляции с понижением версии, была одна строка в коде сервиса:

код версии 5.4:

 [FallbackRoute("/{PathInfo*}", Matches="AcceptsHtml")]
  

v4.5.14 код:

 [FallbackRoute("/{PathInfo*}")]
  

Я еще не разобрался, как реализовать часть ‘matches’ в 4.5.14, однако код, похоже, все еще выполняется и при запуске из VS2017, где сервис запускается как веб-сервис командной строки, однако периодически происходит бесконечное перенаправление. В prod, где приложение запускается как служба Windows, бесконечное перенаправление происходит в 100% случаев.

Результат, когда я посещаю URL:

 https://server.domain.com:port
  

Который должен просто перенаправлять на:

https://server.domain.com:port/login

Что происходит, так это:

 https://server.domain.com:9797/login?redirect=https://server.domain.com:9797/login?redirect=https%3a%2f%2fserver.domain.com%3a9797%2flogin%3fredirect%3dhttps%253a%252f%252fserver.domain.com%253a9797%252flogin%253fredirect%253dhttps%25253a%25252f%25252fserver.domain.com%25253a9797%25252flogin%25253fredirect%25253dhttps%2525253a%2525252f%2525252fserver.domain.com%2525253a9797%2525252flogin%2525253fredirect%2525253dhttps%252525253a%252525252f%252525252fserver.domain.com%252525253a9797%252525252flogin%252525253fredirect%252525253dhttps%25252525253a%25252525252f%25252525252fserver.domain.com%25252525253a9797%25252525252flogin%25252525253fredirect%25252525253dhttps%2525252525253a%2525252525252f%2525252525252fserver.domain.com%2525252525253a9797%2525252525252flogin%2525252525253fredirect%2525252525253dhttps%252525252525253a%252525252525252f%252525252525252fserver.domain.com%252525252525253a9797%252525252525252flogin%252525252525253fredirect%252525252525253dhttps%25252525252525253a%25252525252525252f%25252525252525252fserver.domain.com%25252525252525253a9797%25252525252525252flogin%25252525252525253fredirect%25252525252525253dhttps%2525252525252525253a%2525252525252525252f%2525252525252525252fserver.domain.com%2525252525252525253a9797%2525252525252525252flogin%2525252525252525253fredirect%2525252525252525253dhttps%252525252525252525253a%252525252525252525252f%252525252525252525252fserver.domain.com%252525252525252525253a9797%252525252525252525252flogin%252525252525252525253fredirect%252525252525252525253dhttps%25252525252525252525253a%25252525252525252525252f%25252525252525252525252fserver.domain.com%25252525252525252525253a9797%25252525252525252525252flogin%25252525252525252525253fredirect%25252525252525252525253dhttps%2525252525252525252525253a%2525252525252525252525252f%2525252525252525252525252fserver.petersc
  

Кто-нибудь видел это раньше? Любые предложения о том, с чего начать отладку этого, были бы оценены.

Подробная информация

Итак, я попытался удалить атрибут Authenticate из своего сервиса, чтобы посмотреть, был ли цикл вызван аутентификацией или чем-то еще. Оказывается, это аутентификация, которая вызывает цикл. Как только я закомментировал атрибут, все заработало, как ожидалось.

Обновить

I этот цикл определенно вызван атрибутом AuthenticateAttribute. Я закомментировал строку ‘url = url.AddQueryParam(…’ чтобы я не получал огромную строку запроса с мусором в надежде, что это что-то исправит. Но, похоже, что-то еще не так. Ниже приведены заголовки из первоначального запроса.

 GET https://myServer.myDomain.com:9797/ HTTP/1.1
Host: myServer.myDomain.com:9797
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: ss-pid=qt9Lqb2YvWUu9RzLBlfr
  

Вот заголовки ответа

 HTTP/1.1 302 Found
Transfer-Encoding: chunked
Location: https://myServer.myDomain.com:9797/login
Vary: Accept
Server: Microsoft-HTTPAPI/2.0
Set-Cookie: ss-pid=kczdbSouUzx6aURug3ZU;path=/;expires=Fri, 01 Apr 2039 21:24:01 GMT;HttpOnly
Set-Cookie: ss-id=nAQeqGptASLQ1fZj4xs7;path=/;HttpOnly
X-Powered-By: ServiceStack/4.514 NET45 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type
Date: Mon, 01 Apr 2019 21:24:01 GMT
  

После первого запроса происходит около 60 перенаправлений, которые все выглядят как:

Запрос:

 GET https://myServer.myDomain.com:9797/login HTTP/1.1
Host: myServer.myDomain.com:9797
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: ss-pid=kczdbSouUzx6aURug3ZU; ss-id=nAQeqGptASLQ1fZj4xs7
  

Ответ:

 HTTP/1.1 302 Found
Transfer-Encoding: chunked
Location: https://windows7vm1.petersco.com:9797/login
Vary: Accept
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/4.514 NET45 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type
Date: Mon, 01 Apr 2019 21:24:01 GMT
  

Я не вижу ничего, что указывало бы, почему это должно зацикливаться. Единственное, что изменилось, это версия ServiceStack, почему одна версия находит html-страницу, а другая нет? Есть ли что-то особенное, что мне нужно добавить в версию 4.5.14, чтобы заставить ее отвечать index.html ?

Комментарии:

1. Может ли это быть связано с https? В dev мы запускаем консольное приложение, используя только HTTP, в prod мы настраиваем HTTPS при установке.

2. Любые проблемы с интеграцией, подобные этой, должны включать полные заголовки HTTP-запроса / ответа, чтобы показать, что происходит на самом деле. Я не могу сказать, не видя заголовков, но описание предполагает, что /login страница перенаправляется, это должна быть общедоступная страница для входа пользователей, например. у нее не должно быть какого-либо [Authenticate] атрибута или чего-либо еще. Если вы не используете какие-либо атрибуты аутентификации, я бы посмотрел на все, что у вас есть, что выполняет какие-либо перенаправления, например, то, что вы используете для перенаправления с http на https.

3. Спасибо, я немного разберусь с заголовками и проверю свои перенаправления React. Результаты будут опубликованы завтра.

Ответ №1:

Итак, я не мог поверить, что у атрибута AuthenticateAttribute будет такая вопиющая проблема, ServiceStack слишком зрелый и слишком потрясающий, чтобы это было ошибкой. Итак, используя это предположение (обычно можно с уверенностью предположить, что проблема в вас, а не в гении, который обнаружил ошибку, которую пропустили все остальные), я начал просматривать маршруты и сравнивать их с некоторыми старыми образцами для SPA, доступными на github, и заметил, что ни в одном из них не был определен запасной маршрут.

Мне это показалось странным, но, поскольку я не знаю истории того, как эта функция изначально стала частью шаблона v5.*, я подумал, что удаление этих строк может сработать. Это произошло.

Удаление этого:

 [FallbackRoute("/{PathInfo*}"]
public class FallbackForClientRoutes
{
    public string PathInfo { get; set; }
}
  

И это:

 public object Any(FallbackForClientRoutes request) => 
        new PageResult(Request.GetPage("/"));
  

Все вернулось к нормальному состоянию, переход к базовому URL перенаправляет на ~login, и все методы api возвращаются к аутентификации. Я потерял возможность напрямую переходить к URL, подобномуhttp://myServer.myDomain.com:port/ListCompanies … но я предполагаю, что это также как-то связано с маршрутизацией (так что нужно сделать больше домашней работы).