Issues connecting to a web service in C# - c#

I am using a third party wsdl to connect to a service. I have been provided a security certificate and a username / password.
I have:
Installed the certificate on my Windows 7 machine
Ensured it has the correct permissions
Have the correct location for the API stored in the web.config
The code fails each time. The error messages change, but they include:
Authentication failed because the remote party has closed the transport stream.
An existing connection was forcibly closed by the remote host
Could not create SSL/TLS secure channel
This is the code I am executing:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
//Third party client
var client = new ConnectionPortClient();
//Including these two lines or not does not affect the outcome
//client.ClientCredentials.UserName.UserName = "username";
//client.ClientCredentials.UserName.Password = "password";
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(#"C:\..\cert.p12", "password", X509KeyStorageFlags.MachineKeySet);
var results = client.getResults("");
And here is the relevant part of the web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="assessmentBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://endpoint/" binding="basicHttpBinding"
bindingConfiguration="assessmentBinding" contract="API.Assessment"
name="assessmentSOAP" />
</client>
</system.serviceModel>
Any thoughts on what's going on here?

you use Certificate message credential type but you are trying to set up UserName/Password for UserName message credential type - this is wrong. check the article about Message Security with a Certificate Client

Related

WCF throws error intermittently for the first time whenever I access if after a long time

WCF throws below error intermittently whenever I access the service for the first time in day or after long time.
"The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
Otherwise, it works fine in every case. I am not able to understand why this error occurs?
P.s : I have referred many threads and tried config changes,checked proxy mismatching, but none of them worked for me.
please guide me otherwise I have to put retry option in the service
Update
Client config
<endpoint address="xxxxx" binding="basicHttpBinding" bindingConfiguration="Binding1" contract="IService" name="BasicEndPoint" />
<binding name="Binding1" maxReceivedMessageSize="99999999"
closeTimeout="00:05:00" openTimeout="00:05:00"
sendTimeout="00:05:00" receiveTimeout="00:05:00" >
<readerQuotas maxStringContentLength="99999999" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<binding name="BasicEndPoint" closeTimeout="00:03:00" openTimeout="00:03:00"
receiveTimeout="00:10:00" sendTimeout="00:03:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
Service config:
<binding name="Binding1" maxReceivedMessageSize="99999999">
<readerQuotas maxStringContentLength="99999999" />
<security mode="None">
</security>
</binding>
Okey, I have had a lot of strange error messages during the time I have been working with WCF services. What I learned from that is that they do not alwats make that much sense.
When that said, when you describe yur problem, it sounds like one issue I had with one of the WCF services I have worked with that used named pipes. That was a problem related to the activation. Then I had to refresh the service address in the browser then it worked fine. To solve that it was a permission issue.
Anouther thing that have been gining me error messages is that the namespace and contract to the service is correct in the web.config.
When I was googling your error message, there seems like some people get this have issues with enum in the service. I do not think that's your issue, but maybe... WCF catches exception " The server did not provide a meaningful reply.."

The caller was not authenticated by the service wsDualHttpBinding

I have searched and tried to apply the solution given on the other posts, but i cant solve my problem yet.
I have to use wsDualHttpBinding for duplex connection.
When I try to run my client on the same machine with the WCF server, it can run perfectly, but when i move the client to other machine on the same domain, it return an error "The caller was not authenticated by the service"
here is the app.config on my client
<wsDualHttpBinding>
<binding name="duplexendpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/>
</security>
</binding>
</wsDualHttpBinding>
then i tried to give the credential via the code :
client.ClientCredentials.Windows.ClientCredential.UserName = "serverusername";
client.ClientCredentials.Windows.ClientCredential.Password = "serverpassword";
client.ClientCredentials.Windows.ClientCredential.Domain = "serverdomain";
and it give an error "Client is unable to finish the security negotiation within the configured timeout"
is there any way to solve my problem? thanks.
oke I have found the solution for my problem, i have to turn off the firewall from the client machine.

WCF over HTTPS and Signing the body

I've got a SOAP service I want to connect to. It needs to be accessed trough https and it needs to have it's body signed by a certificate.
I've tried the following code:
<basicHttpBinding>
<binding name="P4Binding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
Setup up my client as follows:
P4_ServiceReference.P4PortTypeClient client = new P4_ServiceReference.P4PortTypeClient();
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
client.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(#"[..].cer");
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(#"[..]", "somepass");
Even changed my Reference.cs to include the ProtectionLevel=ProtectionLevel.Sign on the ServiceContractAttribute and the OperationContractAttribute.
What happens is that the wse:security header is created, but the body is not being signed. The service returns Element http://schemas.xmlsoap.org/soap/envelope/Body must be signed.
What am I missing so that the body gets signed properly?
Fixed it using this customBinding instead of the basicHttpBinding.
//Setup custom binding with HTTPS + Body Signing + Soap1.1
CustomBinding binding = new CustomBinding();
//HTTPS Transport
HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
//Body signing
AsymmetricSecurityBindingElement asec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
asec.SetKeyDerivation(false);
asec.AllowInsecureTransport = true;
asec.IncludeTimestamp = true;
//Setup for SOAP 11 and UTF8 Encoding
TextMessageEncodingBindingElement textMessageEncoding = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
//Bind in order (Security layer, message layer, transport layer)
binding.Elements.Add(asec);
binding.Elements.Add(textMessageEncoding);
binding.Elements.Add(transport);
It seems that TransportWithMessageCredential only uses the Transport for security and ignores everything else.

C# WCF Client takes too long to opened state (DuplexClientBase<T>.Open())

I'm having a little problem with a WCF client. First, allow me to explain and give you details.
I'm currently developing a system, and I was thinking in separate the main application because I designed it to be updated with dlls. So I found MEF, and began to read a lot about it. But there was problem with MEF, it locks the file, no write. Then I found shadow copy. So now I placed the client in another AppDomain in the main Application. I've read that communication cross domains is possible through NET Remoting, so I made research and done it with WCF.
The main Application is the host, it loads the assembly in a new domain and starts the client. As the client is a DLL, there is no AppConfig file to load bindings, endpoints. I've created a class that helps me with that, so the config is added programatically.
Finally, it works!
But there is a little thing I don't think is ok. In the client, when the instruction DuplexClientBase.Open() is executed, it takes 20 seconds to open. I think is not OK 'cause when I move the client to a EXE (remember is a DLL and the config is added programatically) it doesn't take all that time.
Maybe is something wrong in the config, but I can't find it. So here are the souce code files. First, this is the App.config file, when the client is in a console application:
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="TcpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<wsDualHttpBinding>
<binding name="HttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8080/ProtoServicio/EPServicioTcp"
binding="netTcpBinding" bindingConfiguration="TcpBinding"
contract="TestServicio.IServicio" name="TcpBinding">
<identity>
<userPrincipalName value="OlinzerLaptopV\Olinzer" />
</identity>
</endpoint>
<endpoint address="http://localhost:8081/ProtoServicio/EPServicioHttp"
binding="wsDualHttpBinding" bindingConfiguration="HttpBinding"
contract="TestServicio.IServicio" name="HttpBinding">
<identity>
<userPrincipalName value="OlinzerLaptopV\Olinzer" />
</identity>
</endpoint>
</client>
</system.serviceModel>
And now, this is the code that creates the binding and endpoint:
internal static Binding GetBinding()
{
WSDualHttpBinding binding = new WSDualHttpBinding();
TimeSpan span = new TimeSpan( 0, 1, 0 );
binding.Name = "HttpBinding";
binding.CloseTimeout = span;
binding.OpenTimeout = span;
binding.ReceiveTimeout = span;
binding.SendTimeout = span;
binding.BypassProxyOnLocal = false;
binding.TransactionFlow = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MaxBufferPoolSize = 524288;
binding.MaxReceivedMessageSize = 65536;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = Encoding.UTF8;
binding.UseDefaultWebProxy = true;
binding.ReaderQuotas = new XmlDictionaryReaderQuotas();
binding.ReaderQuotas.MaxDepth = 32;
binding.ReaderQuotas.MaxStringContentLength = 8192;
binding.ReaderQuotas.MaxArrayLength = 16384;
binding.ReaderQuotas.MaxBytesPerRead = 4096;
binding.ReaderQuotas.MaxNameTableCharCount = 16384;
binding.ReliableSession = new ReliableSession();
binding.ReliableSession.Ordered = true;
binding.ReliableSession.InactivityTimeout = span;
binding.Security.Mode = WSDualHttpSecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
binding.Security.Message.NegotiateServiceCredential = true;
binding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
return binding;
}
The file created by the code only contains the Http Endpoint. Maybe adding the tcp endpoint could make the diference, but, I have no idea how to make it. The function above is called by the constructor of the ClientClientBase class.
ServiceModel.DuplexClientBase<Servicio> MyClient = new ...<Servicio>(new InstanceContext(this), GetBinding(), GetEndpoint());
Feel free to notify me if you need anything else.
You are doing cross AppDomain communication within single process and you are using WsHttpBinding? Do you understand how big overhead this has? It also highly increases complexity of your application deployment. It is probably not source of your main problem but I would start with:
Replacing WsDualHttpBinding with NetNamedPipeBinding
To diagnosing your issue start with WCF tracing and check which operation on both client and server takes a long time - there can be problem with some security resolving because your setting uses message security.

Connecting to an asmx webservice with WCF through a proxy

Sorry answer found while typing
I am trying to connect to an external webservice that requires username/password authentication through a proxy. I am using Visual Studio Express 2008 to generate a service reference
I have connected to the same
webservice using a web reference.We
only had to set a larger timeout
because it takes a long time to
finish.
I have connected to another
webservice that does not require
username/password authentication
with a generated service reference
and some settings to get it through
the proxy.
So my thought would be to
take this reference, point it to the
correct webservice and add
authentication.
The config I am using without security:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy bypassonlocal="False" proxyaddress="http://***.***.****:80" />
</defaultProxy>
</system.net>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="AreaWebServiceSoap12">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://www.****.*****.****.com/samplewebservice/service.asmx"
binding="customBinding" bindingConfiguration="AreaWebServiceSoap12"
contract="ServiceReference1.ServiceSoap" name="ServiceSoap" />
</client>
</system.serviceModel>
</configuration>
I have added te following code to my call for authentication:
static void Main(string[] args)
{
ServiceSoapClient s = new ServiceSoapClient();
s.ClientCredentials.UserName.UserName = #"username";
s.ClientCredentials.UserName.Password = #"password";
Service.RawGpsData[] result = s.GetRawGpsData(0);
Console.WriteLine(String.Format("done:{0}",result.Length));
Console.ReadLine();
}
Just using this setup gives an error as expected:
The HTTP request is not authorized with client authentication scheme Anonymous. The authentication header from the server is received, is NTLM.
Now I get lost and start trying silly things because I am just starting to use WCF.
When I add the following section to the config
<security authenticationMode="UserNameOverTransport"></security>
I get the following error:
The binding CustomBinding.http: / / tempuri.org / for the contract AreaWebServiceSoap.AreaWebServices is configured with a verification mode for which a transport level with integrity and confidentiality is required. The transport can not provide integrity and confidentiality.
Sorry, while typing this question I stumbled upon the answer myself. I still think people might be interested in this and all comments and thoughts are still welcome. So I will leave the question here and make it community and post the answer myself.
Change the binding to :
<?xml version="1.0" encoding="utf-8" ?>
<customBinding>
<binding name="AreaWebServiceSoap12" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="00:20:00" sendTimeout="00:05:00">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Ntlm"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
So set authenticationScheme="Ntlm"
And here is how you can connect without proxy:
http://blog.bodurov.com/Create-a-WCF-client-for-asmx-web-service-without-using-web-proxy

Categories

Resources