C#:在进行SOAP调用时如何使用HTTP身份验证?

时间:2015-02-23 20:34:35

标签: c# visual-studio-2010 web-services soap http-headers

所以我正在尝试对使用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

有人碰巧知道我在这里做错了吗?

1 个答案:

答案 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;
    }

有了这个,我不再收到身份验证错误了!