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
Related
We have a CRM2011 plugin running async which needs to connect to a webservice to get some missing data. The way i'm trying to solve this is to use a webservice client, made using 'add service reference'.
But for configuration i don't want to hard code the endpoint and binding. So i thought i would just load the configuration for the webservice using OpenMappedExeConfiguration like so.
var config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap{ ExeConfigFilename = #"c:\Path\to\config.xml"}, ConfigurationUserLevel.None);
The config file is loaded... however it is not visible to the client. Because calling
var client = new MyDataServiceClient();
will throw
InvalidOperationException :
Could not find default endpoint element that references contract
'MyDataService.IMyDataService' in the ServiceModel client
configuration section. This might be because no configuration file
was found for your application, or because no endpoint element
matching this contract could be found in the client element.
The configuration file i'm using is:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyDataService" 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="Ntlm" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="https://integrationservices-dev.thecompany.com/MyDataService/MyDataService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyDataService"
contract="MyDataService.IMyDataService"
name="BasicHttpBinding_IMyDataService" />
</client>
</system.serviceModel>
</configuration>
I know i could initialize a binding and endpoint and give those to the MyDataServiceClient(Binding, Endpoint) constructor. But i rather don't want to write my own configuration loader logic.
Is there a way to make the loaded config known to the code constructing the client? If not what other options are there ?
You are trying to read a exe configuration but you are on Web Context, I think you must use OpenWebConfiguration.
In short this command opens the Web-application configuration file as a Configuration object.
Alternatively you can add your configuration into web.config on CRM site
See this Stackoverflow article
See MSDN
I wanted to confirm something.
Below is how I am spinning up a call to my WCF web service in my ASP.NET application.
var xml = "my xml string";
var ep = new EndpointAddress("http://myendpoint");
xml = new Proxy.ServiceClient(new NetTcpBinding(), ep).getNewXML(new Proxy.CallContext(), xml);
My web config looks similar to below. My question is, even though these settings are in the web config, the fact that my calls above are newing up the a service client and fresh New TCP binding everytime tell me that these settings aren't being referenced. Is this correct based on above?
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_SCSService" 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>
</bindings>
<client>
<endpoint address="net.tcp://myendpoint"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_SCSService"
contract="Proxy.Service" name="NetTcpBinding_SCSService">
<identity>
<userPrincipalName value="user#user.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
That's correct. In this case, you are not using the configuration settings found in the config file.
Proxies typically derive from the abstract class ClientBase<T> which provides several different ways to create an instance of a client proxy. Some of the constructors listed will use all of the config file while others will attempt to use the config file to fill in the information that has not been explicitly supplied in the constructor. There are even constructor overloads which do not use the configuration file at all which ClientBase<TChannel>(Binding, EndpointAddress) is one of them.
If you wanted to use what was in the application configuration file, you could use:
var client = new Proxy.ServiceClient("NetTcpBinding_SCSService");
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.
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
I have read several posts where users were having this same issue. When compiled, the .exe is unable to load any resources from app.config. This is occurring even when the app.config is copied to the output directory.
Specifically, I'm having an issue with a web service client being unable to determine the proper endpoint configuration, even if I statically compile it in like this:
this.ws = new MyServicePortTypeClient("MyServicePort", "http://mysite.com/customer_portal/ws.php");
The exception thrown states "System.InvalidOperationException: Could not find default endpoint element that references contract 'MyWebService.MyServicePortType' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
I'm at a loss so any help would be appreciated.
Edit: Here's the MyService.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyServiceBinding" 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="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://mysite.com/customer_portal/ws.php"
binding="basicHttpBinding" bindingConfiguration="MyServiceBinding"
contract="MyWebService.MyServicePortType" name="MyServicePort" />
</client>
</system.serviceModel>
</configuration>
EXE is taking the settings from FileName.exe.config, not from App.config
The FileName.exe.config should be auto generated when compiling the code, and placed alongside the EXE itself.
Check the folder where you have the EXE.. do you see FileName.exe.config in there?
(Posted as answer due to length and formatting)
Well, I figured it out with the help from the information provided by everyone.
The issue is that installutil.exe is trying to use its own config, instead of the one created by the service. In this case, It's trying to load C:\Windows\Microsoft.NET\Framework\v2.0...\InstallUtil.config.
Now that I've figured that out, I can work with it and get it to work correctly.
Thanks, y'all!