1

我正在尝试连接到 https 网络服务(据我所知不是 .NET)。我无法以任何方式控制对方,我只是得到了一些标准和一个 wsdl 来操作它。

我首先使用添加服务引用创建了客户端,尝试了一些事情,直到解决了一些问题,其中最严重的是我无法将身份验证标头添加到导致失败的消息中。

使用旧的 Add Web Reference 添加了服务,似乎更容易管理和适当,使用部分类并覆盖 GetWebRequest,我添加了此代码,以便我可以对服务进行预身份验证并添加安全标头,他们在wsdl 链接。我知道服务不是必须告诉这一点的,但我的 Web 服务创建者伙伴开发人员会很好。

protected override WebRequest GetWebRequest(Uri uri)
{
    HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);

    if (PreAuthenticate)
    {
        NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
        if (networkCredentials != null)
        {
            byte[] credentialBuffer = new UTF8Encoding()
                .GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);

            request.Headers["Authorization"] = "Basic" + Convert.ToBase64String(credentialBuffer);
        }
        else
        {
            throw new ApplicationException("No network credentials");
        }
    }

    return request;
}

要调用该服务,我添加了以下代码:

using (Service client = new Service()) // autogenerated Service class
        {
        client.EnableDecompression = true;

        // Create the network credentials and assign
        // them to the service credentials
        NetworkCredential netCredential = new                             NetworkCredential("test1", "test1");
        Uri uri = new Uri(client.Url);

        ICredentials credentials = netCredential.GetCredential(uri, "Basic");
        client.Credentials = credentials;

        // Be sure to set PreAuthenticate to true or else
        // authentication will not be sent.
        client.PreAuthenticate = true;

        // Make the web service call.

        Request req = new Request { UserName = "test2", Password = "test2"; // an object created from autogenerated code

        RequestResult result = client.processMessage(req); // autogenerated code

    }

在测试此呼叫并与提琴手一起检查我的请求时。我看到 2 个调用带有这些标头的保持活动调用,没什么特别的。

CONNECT server:443 HTTP/1.1
Host: server
Connection: Keep-Alive

发送 570 返回 200 结果。

HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 00:05:13.743
Connection: close

并且调用数据发送 571 结果 500 错误:

POST /host/Service HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5448)
Authorization: BasicdXNlcOTc3MzQyMGTDFTR4dftfrdg5 // changed this hash for security reasons
VsDebuggerCausalityData: // Removed this hash for security reasons
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: server-host-url
Content-Length: 7238
Expect: 100-continue
Accept-Encoding: gzip
Connection: Keep-Alive

.NET 客户端中的错误异常:

Error on verifying message against security policy Error code:1000

如您所见,授权标头存在。我还尝试在 Basic 之后添加一个空格,您可以在上面看到覆盖方法的确切位置,并且似乎提琴手更好地识别它并且还解码了 username:password 标头。

这导致该响应:

HTTP/1.1 500 Internal Server Error
Date: Sat, 21 Apr 2012 21:05:22 GMT
Server: Oracle-Application-Server-11g
X-Powered-By: Servlet/2.5 JSP/2.1
X-Cnection: close
Transfer-Encoding: chunked
Content-Type: text/xml;charset="utf-8"
Content-Language: en
X-Pad: avoid browser bug
Set-Cookie: BIGipServerpoolXoas243_254_9999=437682499.99988.0000; path=/

我首先想知道的奇怪的事情是,如果第一个呼叫应该预先认证,握手保持活动状态?我知道这个 500 错误是在身份验证标头不存在时导致的,但我的却是。Preauthentication 是我需要知道它应该如何发生的事情,我想如果它应该出现在第一条消息中它就不起作用。

另一个奇怪的事情是,如果我更改相反的 2 对密码,我在提琴手上看到我收到 3 条消息,其中 1 条是握手,结果是 200 条,另外“两条”需要 401 授权。

这让我发疯。任何帮助都可以拯救我的灵魂。

谢谢!

4

0 回答 0