繁体   English   中英

仅在从代码(c#)调用时返回未授权(401)

[英]Return Unauthorized (401) only when calling from code (c#)

UPDATE

正如@Alexandru Clonțea所建议的,我检查了提琴手的日志并发现:

无论成功还是失败,实际上都发送了2个请求。 两种情况下的第一个请求几乎都是相同的,就像:

    GET http://myservice.com/handler?param1=something&param2=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&param2=somethingelse
    Date: Sat, 08 Sep 2018 01:50:16 GMT
    Content-Length: 115

    <a href="/handler/?param1=something&param2=somethingelse">Moved Permanently</a>.

我注意到,它总是尝试将调用重定向到/ handler /?param1 = something&param2 = somethingelse ,这是由于服务器代码的设置。 它实际上按预期工作。 区别在于第二个请求。 失败案例的第二个请求(这是C#代码) 没有授权标头 ,这就是失败的原因。 现在,我的问题是,为什么第二个请求会丢失授权标头? 我该如何解决? 以下是失败请求的示例:

GET http://myservice.com/handler/?param1=something&param2=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

背景:我在服务器上部署了用GO编写的服务。 它需要基本身份验证。 例如,我可以通过以下请求成功调用它:

GET /handler/? 
param1=something&param2=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)的信息。 我已经检查了代码发送的实际请求,它具有与上面显示的完全相同的授权标头( Authorization:Basic xxxxxx ,并且xxxxxx与上面的相同)以及相同的uri。 实际上,它发送的所有内容都与我使用rest api客户端工具时的外观相同,但是在代码中只是失败了。

当我在服务器端检查日志时,返回401时会看到以下日志:

[GIN调试]重定向请求301:/ handler-> / hanlder /?param1 = something&param2 = somethingelse

但调用来自其余api客户端工具(或浏览器)时,我看不到此日志

您可能从日志中知道,服务器端代码正在使用go gin框架。 但是,由于在其他情况下它可以正常工作,因此我认为服务器端代码没有问题。

回到C#代码,我尝试使用带有NetworkCredentialHttpWebRequest而不是HttpClient ,并且还尝试使用client.DefaultRequestHeaders.Authorization = auth ,但是我仍然遇到相同的错误。

我想知道是否有人以前见过这个或有帮助吗? 我们将不胜感激。

解决方法是,我可以将请求修改为http://myservice.com/handler/?param1=something&param2=somethingelse,这样就无需重定向。 因此,它将得到正确的授权。

但是,仍然没有弄清楚如何使用授权标头发送第二个请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM