我正在尝试连接到 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 授权。
这让我发疯。任何帮助都可以拯救我的灵魂。
谢谢!