Create WCF Client dynamically - wcf

I want to create a dynamic Connector, to connect to my WCF Service.
I found the following code in the internet:
BasicHttpBinding basic = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
basic.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
EndpointAddress serviceAddress = new EndpointAddress("http://url.svc");
ServiceClient client = new ServiceClient(basic, serviceAddress);
The problem is that in this case I need to know what 'ServiceClient' is. Is it possible to create the Client without the Type?

Related

Using WCF in .net 2

I've got a method of connecting and use a WCF method, which is on HTTPS and requires a username and password in .net 4.
Now I need to do the same but within .Net 2 and I can't seem to get it to work. I keep on getting the below error. Can anyone help?
Error
{"The underlying connection was closed: An unexpected error occurred on a receive."}
Inner Exception
{"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."}
.Net 4 Original Code:
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress ea = new EndpointAddress(wcfURL);
var web = new Gateway.GatewayClient(myBinding, ea);
// var web = new Gateway.GatewayClient();
XMLCrypto crypto = new XMLCrypto();
web.ClientCredentials.UserName.UserName = crypto.DecryptString(username);
web.ClientCredentials.UserName.Password = crypto.DecryptString(password);
web.Open();
web.Inbound("HOLog", message.Trim().Replace("\n", "").Replace(#"\\", ""));
web.Close();
.Net 2 Code
XMLCrypto crypto = new XMLCrypto();
url = "http://..../gateway/gateway.svc";
userName = crypto.DecryptString(userName);
password = crypto.DecryptString(password);
var web = new Gateway.Gateway();
var credentials = new NetworkCredential(userName, password);
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new Uri(url), "Basic", credentials);
web.Credentials = credentials;
string returnMessage = web.Inbound("LSOA", " ");
After a long trolling over the web and testing different ways of talking to a WCF method, I have found the reason why it does not work.
Currently the WCF is set to use wsHttpBinding and now I know that .net 2, does not support it. My work around was to change the Binding from wsHttpBinding to basicHttpBinding within the Web.config of the WCF.
To do this and not effect anything using the WCF, I have to create a seprate Sub domain that will ref a WCF with the config that has the corrected Binding.
"The wsHttpBinding is not compatible with the ASMX-style web references used in .NET 2.0."
How to consume WCF wsHttpBinding Service in application built in 2.0?

WCF call function from host application

I'm fairly recent to WCF and trying to figure out the best way to accomplish my requirements.
I have an application hosting a WCF service with the following code:
Uri u1 = new
Uri("http://localhost:8732/Client1/WcfServiceLibrary1/Service1/"); Uri
u2 = new
Uri("http://localhost:8732/Client1/WcfServiceLibrary1/Service1/mex");
WSHttpBinding binding = new WSHttpBinding();
sHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1), u1);
ServiceMetadataBehavior meta = new ServiceMetadataBehavior();
meta.HttpGetEnabled = true;
sHost.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), binding, u1);
sHost.Description.Behaviors.Add(meta); sHost.Open();
I can create a service reference on a client application and call methods on this service no problems. using the code below.
remoteService.Service1Client client = new remoteService.Service1Client();
remote.Text = client.GetData(3);
I can also call a method without a service reference.
EndpointAddress myEndpoint = new EndpointAddress("http://localhost:8732/Client1/WcfServiceLibrary1/Service1/");
WSHttpBinding myBinding = new WSHttpBinding();
ChannelFactory<IService1> ServiceConnectionFactory = new ChannelFactory<IService1>(myBinding, myEndpoint);
IService1 serviceConnection = ServiceConnectionFactory.CreateChannel();
If I try to execute the same code in the host application it get the error below.
The request channel timed out while waiting for a reply after
00:01:00. Increase the timeout value passed to the call to Request or
increase the SendTimeout value on the Binding. The time allotted to
this operation may have been a portion of a longer timeout.
How can a application consume and use a WCF service that it is currently hosting? Do I need to open the service in a thread of its own?
The idea is for the host to trigger some initialization before clients connect.

.net WCF - CXF/WSS4j interoperability

I would like to consume a CXF web-service from a .net c# client. We are currently working with java-to-java requests and we protect SOAP envelopes through ws-security (WSS4J library).
My question is: how can I implement a C# WS-client which produces the same SOAP requests as the following client-side java code?
//doc is the original SOAP envelope to process with WSS4J
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
//add username token with password digest
WSSecUsernameToken usrNameTok = new WSSecUsernameToken();
usrNameTok.setPasswordType(WSConstants.PASSWORD_DIGEST);
usrNameTok.setUserInfo("guest",psw_guest);
usrNameTok.prepare(doc);
usrNameTok.appendToHeader(secHeader);
//sign the envelope body with client key
WSSecSignature sign = new WSSecSignature();
sign.setUserInfo("clientx509v1", psw_clientx509v1);
sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
Document signedDoc = null;
sign.prepare(doc, sigCrypto, secHeader);
signedDoc = sign.build(doc, sigCrypto, secHeader);
//encrypt envelope body with server public key
WSSecEncrypt encrypt = new WSSecEncrypt();
encrypt.setUserInfo("serverx509v1");
// build the encrypted SOAP part
String out = null;
Document encryptedDoc = encrypt.build(signedDoc, encCrypto, secHeader);
return encryptedDoc;
Does anybody know where I could find a microsoft how-to or a .net working example?
================================ EDIT ====================================
Thank you Ladislav! I applied your suggestions and I came up with something like:
X509Certificate2 client_pk, server_cert;
client_pk = new X509Certificate2(#"C:\x509\clientKey.pem", "blablabla");
server_cert = new X509Certificate2(#"C:\x509\server-cert.pfx", "blablabla");
// Create the binding.
System.ServiceModel.WSHttpBinding myBinding = new WSHttpBinding();
myBinding.TextEncoding = ASCIIEncoding.UTF8;
myBinding.MessageEncoding = WSMessageEncoding.Text;
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
myBinding.Security.Message.AlgorithmSuite =
System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128;
// Disable credential negotiation and the establishment of
// a security context.
myBinding.Security.Message.NegotiateServiceCredential = false;
myBinding.Security.Message.EstablishSecurityContext = false;
// Create the endpoint address.
EndpointAddress ea =
new EndpointAddress(new Uri("http://bla.bla.bla"),
EndpointIdentity.CreateDnsIdentity("issuer"));
// configure the username credentials on the channel factory
UsernameClientCredentials credentials = new UsernameClientCredentials(new
UsernameInfo("superadmin", "secret"));
// Create the client.
PersistenceClient client = new PersistenceClient(myBinding, ea);
client.Endpoint.Contract.ProtectionLevel =
System.Net.Security.ProtectionLevel.EncryptAndSign;
// replace ClientCredentials with UsernameClientCredentials
client.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
client.Endpoint.Behaviors.Add(credentials);
// Specify a certificate to use for authenticating the client.
client.ClientCredentials.ClientCertificate.Certificate = client_pk;
// Specify a default certificate for the service.
client.ClientCredentials.ServiceCertificate.DefaultCertificate = server_cert;
// Begin using the client.
client.Open();
clientProxyNetwork[] response = client.GetAllNetwork();
As a result I get (server-side) the following CXF exception:
java.security.SignatureException: Signature does not match.
at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:421)
at sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:133)
at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:112)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate (PKIXMasterCertPathValidator.java:117)
Therefore it seems a key jks->pem conversion problem... Or am I am missing something in the client-code above?
Well, in the end the solution is to encrypt and sign the whole username token. As for the interoperability, the ws addressing must be activated in cxf and a custom binding in c# is needed. The custom binding that did the trick is basically
AsymmetricSecurityBindingElement abe =
(AsymmetricSecurityBindingElement)SecurityBindingElement.
CreateMutualCertificateBindingElement(MessageSecurityVersion.
WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
           
Wcf signs each ws addressing element, therefore the same must be done server side.
This is usually pretty big problem because WCF does not support UserNameToken Profile with Digested password. I needed it few months ago and we had to implement our own custom binding but that code is not ready for publishing. Fortunatelly this blog article describes other implementation and contains sample code with new UserNameClientCredentials class supporting digested password.
Btw. same security configuration should be possible with older API called WSE 3.0. It was replaced by WCF but still some WS-* stack configuration are much simpler with that API and old ASMX services.

Silverlight 4 NetTcpBinding programmatic configuration

I'd like to configure a NetTcpBinding programatically for a silverlight 4 client. (NetTcpBinding is now supported)
Here is the code I use to do this for a Windows Forms client:
EndpointAddress endpointAddress = new EndpointAddress(uri);
NetTcpBinding netTcpBinding = new NetTcpBinding();
MyServiceClient agentClient = new MyServiceClient(new InstanceContext(this), netTcpBinding, endpointAddress);
For silverlight I added references to System.ServiceModel.Extensions and System.ServiceModel.NetTcp, but this is not not enough : I'm not able to find a NetTcpBinding class.
Where is this class if it exists? Does an equivalent syntax exists? The silverlight 4 runtime must be doing this somehow when a configuration file is used.
You can use a custom binding in place of NetTcpBinding : the code below is working, but I don't know if this is the recommended pattern.
BinaryMessageEncodingBindingElement messageEncoding = new BinaryMessageEncodingBindingElement();
TcpTransportBindingElement tcpTransport = new TcpTransportBindingElement();
CustomBinding binding = new CustomBinding(messageEncoding, tcpTransport);

Given the Following Code how Would i Change/Set my Silverlight WCF Service URI in code?

Given the Following Code how Would i Change/Set my Silverlight WCF Service URI in code?
mySvc.InsertPOCompleted += new EventHandler<SalesSimplicityPO_SL.POSvc.InsertPOCompletedEventArgs>(mySvc_InsertPOCompleted);
mySvc.InsertPOAsync(InitialsTextBox.Text.ToString(), DescTextBox.Text.ToString(), ClientTextBox.Text.ToString());
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress(new Uri("http://localhost/POSystem/POSvc.svc"));
POSvc.POSvcClient mySvc = new POSvc.POSvcClient(binding, address);