UPDATE
Как подсказал @Alexandru Clonțea, я проверил журнал скрипача и обнаружил:
В случае успеха или неудачи фактически отправляется 2 запроса. Первый запрос в обоих случаях практически одинаков, это что-то вроде:
GET http://myservice.com/handler?param1=something¶m2=somethingelse HTTP/1.1
Authorization: Basic xxxxxx
Accept: application/json, application/xml, text/json, text/x-json,
text/javascript, text/xml
User-Agent: RestSharp/100.0.0.0
Host: myservice.com
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Ответ для них одинаков, а именно:
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=utf-8
Location: /handler/?param1=something¶m2=somethingelse
Date: Sat, 08 Sep 2018 01:50:16 GMT
Content-Length: 115
<a href="/handler/?param1=something¶m2=somethingelse">Moved Permanently</a>.
Я заметил, что он всегда пытается перенаправить вызов на / handler /? Param1 = что-то & param2 = somethingelse , и это из-за настройки кода сервера. это на самом деле работает, как ожидалось. Разница во втором запросе. Второй запрос случая сбоя (это код c #) не имеет заголовка авторизации , и поэтому он не прошел. Теперь мой вопрос: почему во втором запросе отсутствует заголовок авторизации? Как я могу это исправить? Ниже приведен пример неудавшегося запроса:
GET http://myservice.com/handler/?param1=something¶m2=somethingelse HTTP/1.1
Accept: application/json, application/xml, text/json, text/x-json,
text/javascript, text/xml
User-Agent: RestSharp/100.0.0.0
Accept-Encoding: gzip, deflate
Host: myservice.com
Backgroud:
У меня есть служба, написанная на GO, развернутая на сервере. Требуется базовая аутентификация. Например, я могу успешно позвонить по следующему запросу:
GET /handler/?
param1=something¶m2=somethingelse HTTP/1.1
> Host: myservice.com
> Authorization: Basic xxxxxx
> User-Agent: RestClient/5.16.6
> Accept: */*
Запрос выше сделан клиентским инструментом rest api (например, почтальоном), и он работает нормально. Это также работает нормально, если я позвоню из браузера.
Проблема:
Теперь я пытаюсь сделать тот же вызов той же службе, используя код C #, и у меня это как:
// pass cert validation
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
HttpClient client = new HttpClient();
var byteArray = Encoding.ASCII.GetBytes(username + ":" + password);
var auth = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Authorization = auth;
var response = client.SendAsync(request).Result; // don't need async
Но в этом случае я получаю Несанкционированный (401) обратно. Я проверил на самом деле запрос, который был отправлен кодом, у него был точно такой же заголовок авторизации, как показано выше ( Авторизация: Basic xxxxxx , и xxxxxx такой же, как указано выше) и тот же URI также. На самом деле все, что он отправлял, выглядит так же, как когда я использовал клиентский инструмент rest api, но в коде это просто не получилось.
когда я проверяю журнал на стороне сервера, я вижу журнал ниже, когда он возвращает 401:
[GIN-debug] запрос на перенаправление 301: / handler -> / hanlder /? Param1 = что-то & param2 = что-то другое
но я не вижу этот журнал, когда вызов из клиентского инструмента rest api (или браузера)
Как вы, возможно, знаете из журнала, код на стороне сервера использует платформу go gin. Но поскольку в других случаях он работает нормально, я не думаю, что это проблема с кодом на стороне сервера.
Возвращаясь к коду C #, я попытался использовать HttpWebRequest с NetworkCredential вместо HttpClient , и я также пытаюсь использовать client.DefaultRequestHeaders.Authorization = auth , но я все еще получаю ту же ошибку.
Мне интересно, видел ли кто-то это раньше или мог бы помочь? Это будет действительно оценено.