我正在尝试使用 SOAP Webservice客户端对象执行NTLM身份验证,但失败并出现以下异常:
HTTP请求未经客户端身份验证方案'Ntlm'的授权。从服务器收到的身份验证标头是“ NTLM ###我收到的令牌###”。
当使用 HttpWebRequest对象执行请求时,它运行正常。
这是我的示例客户代码:
class Program {
static void Main(string[] args) {
EndpointAddress endpointAddress = null;
BasicHttpBinding basicClientBinding = null;
HttpRequestMessageProperty httpRequestProperty = null;
myWebObject myObject = new myWebObject() { Id = new Guid(), Attribute1 = "Value 1" };
myWebServiceClient myServiceClient = null;
update myUpdateObject = new update();
myUpdateObject.customObject = myObject;
updateResponse myResponse = null;
HttpWebRequest request = null;
WebResponse response = null;
string sb = string.Empty;
string username = "Username";
string password = "Password";
//Endpoint
endpointAddress = new EndpointAddress("https://mydomain/endpoint?wsdl");
//avoid SLL Certificate Errors
System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
//use TLS 1.2
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//Basic HTTP Binding
basicClientBinding = new BasicHttpBinding();
basicClientBinding.Name = "BasicHttpBinding";
if (endpointAddress.Uri.Scheme == "https") {
basicClientBinding.Security.Mode = BasicHttpSecurityMode.Transport;
} else {
basicClientBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
}
basicClientBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
basicClientBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
//SOAP Client
myServiceClient = new myWebServiceClient(basicClientBinding, endpointAddress);
myServiceClient.ClientCredentials.UserName.UserName = username;
myServiceClient.ClientCredentials.UserName.Password = password;
//HttpWebRequest
request = (HttpWebRequest)HttpWebRequest.Create(endpointAddress.Uri);
request.Method = "POST";
//NTLM Authentication
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(endpointAddress.Uri, "NTLM", new NetworkCredential(username, password));
request.Credentials = credentialCache;
//add Custom Header
request.Headers.Add(
"MyAuthorization",
"Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(
username + ":" + password)
)
);
sb = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><update xmlns=\"http://myservice.webservice.product.mydomain.com/\"><object Id=\"00000000-0000-0000-0000-000000000000\" xmlns=\"http://product.mydomain.com/myservice/object\"><Attribute1>Value 1</Attribute1></object></update></s:Body></s:Envelope>";
Stream firstStream = request.GetRequestStream();
using (Stream st = firstStream) {
using (StreamWriter writer = new StreamWriter(st)) {
writer.Write(sb);
}
}
try {
if (args.Length > 0) {
//This Request WORKS
response = request.GetResponse();
} else {
//This Request FAILS
myServiceClient.Open();
using (OperationContextScope scope = new OperationContextScope(myServiceClient.InnerChannel)) {
//add Custom Header
httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("MyAuthorization",
"Basic " +
Convert.ToBase64String(Encoding.UTF8.GetBytes(
username + ":" + password)));
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//Calling Webservice
myResponse = myServiceClient.update(myUpdateObject);
}
myServiceClient.Close();
}
} catch (Exception ex) {
throw new Exception(ex.Message);
}
}
}