如何使用SOAP Web服务客户端处理NTLM身份验证?

时间:2019-01-10 08:42:53

标签: .net authentication soap httpwebrequest ntlm

我正在尝试使用 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);
        }
    }
}

0 个答案:

没有答案