所以我正在尝试对使用HTTP身份验证的Web服务进行SOAP调用。我在Visual Studio中添加了一个Web引用,它为我生成了一个包装类。以下是我如何进行通话的示例代码:
var prox = new WebserviceNamespace.WebService();
prox.Credentials = new NetworkCredential("username", "password");
prox.PreAuthenticate = true;
var resp = prox.webMethod(null, null);
最后一行抛出“身份验证失败”消息。
我使用wireshark来检查它是否正在尝试向HTTP数据包添加基本身份验证,但它看起来并不像。这是wireshark输出:
POST /cms/services/WebService HTTP/1.1\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.34209)\r\n
VsDebuggerCausalityData: uIDPo7e/OYIGV2VDs7nYMO5QmegAAAAAWxFxk5NzcUSF5zGIxQ1REwb488ITippOiEKaDSmuFDkACQAA\r\n
Content-Type: text/xml; charset=utf-8\r\n
SOAPAction: ""\r\n
Host: sub.domain.com\r\n
Content-Length: 343\r\n
Expect: 100-continue\r\n
Connection: Keep-Alive\r\n
\r\n
[Full request URI: http://sub.domain.com/cms/services/WebService3.0]
[HTTP request 2/2]
[Response in frame: 265321]eXtensible Markup Language
<?xml
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<webMethod
xmlns="WebService">
<in0 xsi:nil="true"/>
<in1
xsi:nil="true"/>
</webMethod>
</soap:Body>
</soap:Envelope>
我希望在HTTP身份验证中看到这样的一行:
Authorization: Basic SUNOOnNwc3pK
有人碰巧知道我在这里做错了吗?
答案 0 :(得分:2)
终于弄明白了。这篇非常小的文章为我提供了关键:http://blog.kowalczyk.info/article/at3/Forcing-basic-http-authentication-for-HttpWebReq.html
基本上,只有在服务器质询您的请求时才会使用Credentials属性。如果服务器没有挑战它可能会失败(就像发生在我身上)。我要做的是编辑自动生成的代理类,将此代码添加到它(受上面的链接启发):
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
String authInfo = Convert.ToBase64String(Encoding.Default.GetBytes("username:password"));
request.Headers["Authorization"] = "Basic " + authInfo;
return request;
}
有了这个,我不再收到身份验证错误了!