In a Project being upgraded I have to Consume a WCF service ( Service A) published by 3rd party ( no Control) in my WCF Service.
I have been using ServiceA in My Web App project ( vs2008) and it has been working fine.
I started by Adding Service Reference in my WCF Project ( ServiceB). Lets say Name of the Service is "XYZ". VS created all required files but when I tried to compile it gave error
The type name 'XYZ' does not exist in the type 'ServiceB.ServiceB';
My 'Service B' has 'ServiceB.SVC'
I tried to overcome this by removing namespace "ServiceB." from Reference.cs file and Its content. This code could then be compiled.
Now I get Exception that
"The caller was not authenticated by the service."
Inner exception
The request for security token could not be satisfied because authentication failed.
at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
=>
((System.ServiceModel.FaultException)(ex.InnerException)).Message
The request for security token could not be satisfied because authentication failed.
The Web.Config File on ServiceB is as follows:
<wsHttpBinding>
<binding name="WSHttpBinding_IABCService" 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" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://aaaaa/ ServiceA.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IABCService"
contract="XYZ.IABCService" name="WSHttpBinding_IABCService">
<identity>
<servicePrincipalName value="host/[hostname]" />
</identity>
</endpoint>
</client>
======
I made my self believe that may be the problem is in WCF accessing WCF. I created a Web Service (.asmx) and added reference to ServiceA . When I debug by invoking the method I get the results from ServiceA . Hoping this was a solution that I can use till I figure out between WCF and WCF issue, I added reference to asmx service to My WCF Service ( ServiceB).
When I debug by Running ServiceB --> asmx --> Service A, I again get Authentication failed for user error!!!
I believe it has something to do with Identity being impersonated ...
I read that ServiceB's web.config taking Priority over asmx web.config but I was not able to get to a solution.
I cannot turn off " Security Mode=None" as then Service A responds by saying no tokens were passed.
Any help will be appreciated:
Remember that I am able to use the WC Service A from WebApp and from asmx but not from another WCF directly or Indirectly.
Thank you
Mar
This has nothing at all to do with WCF calling WCF. Try to imagine that WCF calling WCF causes compile errors - and that you're the first person in the world to discover this since 2006!
Try to fully qualify the "XYZ" type, spelling out the full namespace. If that doesn't work, then right-click each service reference and choose "View in Object Browser". Look to see what the full name of the types is.
If none of this helps you, then please post complete error messages and/or exceptions.
And, please don't ever edit Reference.cs. Any of your edits would be destroyed the next time that "Update Service Reference" is performed. Therefore, any change you think you want to make to Reference.cs can either be done in a better way without changing it, or else you really don't want to make that change at all (like the change you made).
It seem to me that you need to have a delegation instead of impersonation. To convert current users token to another one you can use DuplicateToken DuplicateTokenEx (the last one can produce TokenPrimary) with SecurityDelegation
SecurityImpersonation (SECURITY_IMPERSONATION_LEVEL) and then WindowsIdentity(IntPtr) constructor. See LogonUser and delegation as a example.
Another way is Protocol Transition: S4U, S4U2Self (see http://msdn.microsoft.com/en-us/magazine/cc163500.aspx, http://msdn.microsoft.com/en-us/library/ff650469.aspx, http://msdn.microsoft.com/en-us/library/ms998355.aspx). You can use something like new WindowsIdentity(clientUPN).Impersonate().
If you have to do a delegation (i.e. act as original caller) process is described in detail on this MSDN Forum thread. Don't use a full trust delegation -- it requires admin permissions for AD and it is not a good thing from security prospective. Constrained delegation is easy to setup correctly if you know which names to use in SETSPN command. Also make sure you run service B (the delegator) using domain user account, machine accounts like Network Service/Local Service or local user accounts won't work because you won't be able to create SPN for those.
Related
I followed this tutorial (at least based my WCF in this, coz I need then to work alike):
http://www.eggheadcafe.com/tutorials/wcf/b5ada8df-58c5-492f-b368-457b3a4f137c/notify-client-applications-using-wcf-callbacks.aspx
It's working very well on my computer, but i need to use it over the internet. While trying to do this I heard (over the internet) that is better to use netTcpBiding.
I gonna have a server that is going to be aware of the number of clients online. I wanted a WFC service on my IIS in the server, and a windows service consuming it and notifying it. I need the callback coz the server sometime have to be able to execute some commands on the client.
I would be very pleased if anyone could help me.
Thanks in advance,
Edit:
Making myself clear: I just could not make it work over the internet. Can you guys show me how can i change my configurations (Web.config e App.config) to use netTcpBinding and work over the internet?
Thanks again,
Edit 2:
My Web.config in my WCFServiceApplication is:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IPCWatcherWCFService" 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>
<services>
<service behaviorConfiguration="TiT.PCWatcher.Server.WCFService.Services.PCWatcherWCFServiceBehavior" name="TiT.PCWatcher.Server.WCFService.Services.PCWatcherWCFService">
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IPCWatcherWCFService" contract="TiT.PCWatcher.Server.WCFService.Interfaces.IPCWatcherWCFService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TiT.PCWatcher.Server.WCFService.Services.PCWatcherWCFServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
My App.config in my WindowsService is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IPCWatcherWCFService" 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="http://localhost:25145/Services/PCWatcherWCFService.svc"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IPCWatcherWCFService"
contract="PCWatcherWCFServiceReference.IPCWatcherWCFService"
name="WSDualHttpBinding_IPCWatcherWCFService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Just changing it to netTcpBinding does not work...
But i would be glad enough to jut be able to run this over the internet... I published the WCFService on IIS. Links:
https://www2.tcenter.com.br/monitor/PCWatcherWCFService.svc
OR
http://www2.tcenter.com.br:8080/monitor/PCWatcherWCFService.svc
Just changing the configs its enought to make it work through the internet? like i said, local it works just fine.
I thought that just changing the endpoint address on the client to one of the URL's above it whould work, but it did not...
The example that you linked hosts the service on the WPF. I don't know if it applys to my cenario...
i Think i'm gonna stick with the DualHttpBinding, you don't think that port forwarding it's good for my needs, i'm can have a lot of clients in one intranet and having the router decide wich one he is going to send info for it's no good right? or there's a way to make the router respond corretly to each and every machine conecting to my webserver through the same port?! (just asking, hehehe)
Thanks a lot in advance,
Edit on 21/06/2012:
Thanks for the reading.
I was not able to get the service to work with netTcpBinding in LAN.
I did a mock sample of my cenario. It's here. Called DualCommunicationTest.
When I started this post, i just wanted to know how to make this cenarion runing on internet. Just that.
During my time searching for a solution before posting here, i readed that netTcpBinding is better. So i asked about it. It was just a side question.
So... my current needs on the post are:
How to use the sample i developed on the internet.
OR
How to make the sample i developed work with netTcpBinding AND then be able to use it on the internet. (I'm pretty sure Clunky Coder taught me the second part, on how to publish a net.tcp on the internet with the IIS and stuff, thanks a lot for that, but i was not able to test it yet, because i couldn't do a netTcp yet.)
I'm sorry if i'm not been clear enough, my English is not so good. sry and thanks again, a lot.
netTcpBinding is better for duplex communication (communication with callbacks) and it's more performant than WSDualHttpBinding which is the preferred binding for duplex communication over HTTP. But you shouldn't really use netTcpBinding over the internet although you technically can and it might work, but the ports that netTcpBinding uses may be (and usually are) blocked by firewalls on the internet. When you send something across the internet, it makes lots of hops and goes through lots of routers and firewalls, and there is no guarantee that those routers and firewalls will have all ports open. But if you can open the ports (for netTcp it's TCP 808) on both the client and server endpoints (usually done by port forwarding on the router) it may work, but the general advice is not to use netTcpBinding over the internet. Having said that I have used it a couple of times for my services, and my clients have been able to consume the service over the internet without any problems-after I forwarded the ports on both the client and server ends.
In general for duplex communication over the internet you have the WSDualHttpBinding and if you have a Silverlight client (Silverlight doesn't support WSDualHttpBinding) you can use PollingDuplexHttpBinding.
I also recommend you read this.
EDIT:
To change that example to use netTcpBinding, just change the bindings in the config file to use netTcpBinding instead of wsDualHttpBinding. Have a look at this article, it does what the link you posted does, with netTcpBinding and more explanation.
EDIT 20/06/2012:
Making myself clear: I just could not make it work over the internet.
Can you guys show me how can i change my configurations (Web.config e
App.config) to use netTcpBinding and work over the internet?
Seems that you were able to get the service to work with netTcpBinding in LAN, so your earlier problem is now fixed and you're now having trouble hosting the service in IIS and publishing it online. When your service works in a LAN, it will work over the internet once you host it in IIS and forward the appropriate ports on the clients and servers routers, this is a common scenario and is documented well online. To do this You must host your service as an application in your IIS website. You need to make sure your service has a .svc file that points to the location of the service, then copy the contents of
the App.Config (Service config file) to a new web.config (in the same physical directory as your App.config) and also remove the <host><baseAddresses> section in the newly created web.config, point the physical path of the application to the location of this service on your service host computer. Once that's taken care of, just be sure to edit the default website bindings to enable the specific bindings your service uses, for netTcpBinding go to: Website -> 'Edit Bindings...' -> 'Add...' then choose net.tcp and assign it the ports.
Then on your application go to 'Advanced Settings' and enable net.tcp, netTcpBinding service will typically have http,net.tcp as it's enabled protocols. If you run into teething errors make sure the default app pool (or which ever application pool your website is using) has the required permissions to access and read the physical directory on the server in which the service resides.
Please read this and this, asking me to elaborate would just be repeating what they're saying.
EDIT 21/06/2012:
I just downloaded your service and hosted it in IIS and it's hosted fine, since its using HTTP and not nettcp then that means it works perfectly fine on the internet. If your service is something simple and you don't expect to do heavy processing with it (by the looks of it you're just trying to get the list of clients connected to it) then stick with wsDualHTTPBinding since the HTTP protocol will work in any environment and you don't have to worry about firewalls as you would with netTcpBinding. This is all I did to host the service in IIS (and make it available over the internet):
Go to DefaultWebsite in IIS, right click, add application, under Alias just give your service any name you wish to be able to see in the URL. Select Default App Pool or ASP.NET 4.0 app pool.
Point the physical path to where your .svc file is on your computer; for me its:
C:\Users\MyPC\Documents\DualCommunicationTest.Server\WcfServiceApp
Under enabled protocols ensure that you have HTTP on port 80 or any other port, for example 8085, but you will need to forward this port on your router to the Service host computer. If your Service host is on IP 192.168.1.4 in your LAN, then on your router forward port 80 (or whatever port you use-say 8085) to computer 192.168.1.4.
And it's that easy.
TCP binding is better for callbacks over the internet because TCP is dual direction by nature.
HTTP is a request, it is one way only. Hence the dual in dualHttpBinding. WCF has to create a second HTTP connection back to the client so the service can send requests to the client.
The Internet is not really set up for servers to call back via HTTP. Things like NAT being performed by routers means that ports must be forwarded in order to route the HTTP request properly, and the client would have to be running an HTTP server.
So, it is much easier to use TCP. Either that or possibly have the client request a reply object that is streamed from the server end (a never ending reply in effect), that the server can fire notifications down. This isn't simple though.
I firstly launched my subscriber for my WCF service and proceed to publish a posting from my publisher. My subscriber is able to receive the posting.
Secondly I closed my FIRST subscriber and open it again to subscribe to the same service which is so called the SECOND subscriber that has subscribed to the service. And once again, it is able to receive a posting.
Once I repeat this for the third time, there would be a exception of
The message could not be transferred within the allotted timeout of 00:01:00. There was no space available in the reliable channel's transfer window. The time allotted to this operation may have been a portion of a longer timeout.
Summary :
On first client, SUBSCRIBED , everything works fine
Closes first client
On the cilent AGAIN , (meaning second connection on the same service(?)) , everything works fine
Closes "second client"
Opens the client for the THIRD time, error occurs
From what I have researched so far, I have seen that in this question, it mentioned that the default connection limit is 2?
WCF Service Throttling
Is that the issue that is causing my error? IF yes, is it possible to adjust the limit of the connection and how?
Pretty new in the WCF area and welcome anybody to give me their opinion.
Thanks!
EDIT
Tried using UseSynchronizationContext = false on my client. As everytime a posting is sent, my PostReceived() method for my subscriber includes opening a popup windows form containing the information of the posting. When using UseSynchronizationContext = false, the windows form would not be able to open properly(an error here).
Anyone has any idea how to fix that or have any alternate solutions?
EDIT 2
Been reading around lots of WCF connection related stuffs and found out that most people are trying to toggle the maxConnections variable or related in their config files. My question is the only config files I have is in my client and none for my Service project. Is it necessary for me to add a config file for my service project?
As the "connection limit"(?) is 2, I tried the method of unsubcribing it when the client exits the application but that doesn't work and gives me and error. I have posted a question on the error that I received.
https://stackoverflow.com/questions/8395525/objectdisposedexception-on-wcf-service
Config Codes for Client side added :
<system.serviceModel>
<diagnostics performanceCounters="All" />
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IPostingContract" clientBaseAddress="http://localhost:8000/wcfClient/" closeTimeout="00:01:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10: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="http://localhost:8888/PostingContract/Posting"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IPostingContract"
contract="IPostingContract" name="WSDualHttpBinding_IPostingContract">
<identity>
<userPrincipalName value="##" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Would someone advise me if I have done anything wrong for my service part with regards to the behaviors or the config files. Appreciate a million. Thanks!
EDIT 3
Manage to play around with the service behavior. For the behavior, I changed the InstanceContextMode to single.
InstanceContextMode = InstanceContextMode.Single
and that actually allowed me to launch more than 2 connections of my windows form app. However if I do that, If I had launch 2 connections beforehand, for the third connection it will receive 3 popups, and subsequently for the forth connection, it will receive 4. When it is suppose to receive 1.
would that help to add UseSynchronizationContext = false on the client subscriber class
for e.g.
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,
UseSynchronizationContext = false)]
The reason might be of the dealocking callback
similiar post here WCF: Having trouble with one-way callbacks
In my application a Winform UI thread in sync calls a WCF method.
99.99% of the time this is ok, but once in a while the call to the WCF method becomes locked and the UI freezes.
I know I can prevent the freezing of UI by making the call async - most of our WCF calls are async - but we considered it not so bad to make this particular tiny method in sync.
When the lock in the WCF service occurs other users cannot access the service as well. I have to restart the WCF service host (Windows service) to resolve the problem.
How is it possible for a WCF service to become locked and inaccessible?
I can't think of a scenario.
We checked the database, which was running as usual.
Technical details:
We use a proxy in a service agent. This service agent with its proxy is kept alive while the application runs.
[PreserveReferences]
[OperationContract(IsOneWay = false, AsyncPattern = false, Action = "MyMethod")]
MyType MyMethod();
The binding in use:
<wsHttpBinding>
<binding name="AppWsHttpBindingConfig" transactionFlow="true" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Mtom">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="false" enabled="false" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
Most of the WCF service hang problems is related to disposal of WCF client proxies, which i believe is the problem in your case. If you are not disposing client proxies correctly you will get a timeout exception when you make the (maxConcurrentSessions + 1) n-th call.
Please check out this article.
Basically it says that, if your channel is not in a faulted state, calling Abort on that channel frees the client resources but does not free server resources. For example when a service method throws a FaultException it does not put the channel in a faulted state. So calling abort on this proxy will result in an open session in your server with no client.
Wheter this is your case or not, you should consider using the approach described in that article, or some other with the same idea.
On a production server (Windows Server 2003 SP2) I can connect to a remote WCF service with Internet Explorer 8: When I browse to the URL http://www.domain.com/Service.svc (where my service listens) I get the expected info page of the service displayed. Connection settings in Internet Explorer only specify "auto detect", proxy settings are disabled.
If I start a console application (built with WCF in .NET 4.0) on the same server which also tries to connect to the same WCF service it fails telling me that no endpoint was available listening on http://www.domain.com/Service.svc.
Configuration of the WCF client:
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IMyService" 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"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://www.domain.com/Service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService"
contract="Service.IMyService" name="WSHttpBinding_IMyService" />
</client>
</system.serviceModel>
<configuration>
With these settings I can communicate successfully with the remote service from my development machine.
Looking around for other options I found that I can specify to use the Internet Explorer proxy settings with:
<system.net>
<defaultProxy>
<proxy usesystemdefault="true" />
</defaultProxy>
</system.net>
It didn't work and I am not sure if I understood this setting really correctly. (My hope was that the WCF client will adopt the "autodetect" setting of Internet Explorer and then connect the same way to the service like the installed IE.)
I also had toggled the useDefaultWebProxy setting in the binding configuration between true and false with no success.
Now I am asking for help what I can do? Which settings might be wrong or missing? What could I test and how can I get more detailed error messages to better identify the problem?
Thank you in advance!
Edit:
Stack in Innerexception is saying:
System.Net.WebException: Connection to remote server could not be established
System.Net.Sockets.SocketException: Connection failed since the host didn't answer after a certain time span or the connection was faulted since the connected host didn't answer.
Although Internet Explorer can connect to the service without specifying a proxy address but only enabling the "auto detect" feature this doesn't seem to work with my WCF client when setting <proxy usesystemdefault="true" />. (Documentation says: This will pickup the Internet Explorer settings. But it doesn't work.) Finally the customer gave me a concrete proxy address and I have changed the binding in my client configuration the following way:
Changed: useDefaultWebProxy="false" (instead of true)
Added: proxyAddress="http://10.20.30.40:8080" (Edit2: Not only IP-address! The prefix with http:// is important! Otherwise it will throw new exceptions, see the follow-up question below.)
With this the WebException and SocketConnection disappeared and the Client seems to connect to the Service but I am having now the next issue when calling the first service operation. I will put this in an new question.
Edit: Here is the follow-up question:
Strange exception when connecting to a WCF service via a proxy server
Edit2: According to the answer in the follow-up question it is important to prefix the proxyAddress with http. (changed my answer now)
Did you maybe just introduce a typo into your address on the client??
address="http://www.domain.com/Service.scv"
Shouldn't that be
address="http://www.domain.com/Service.svc"
(.svc instead of .scv at the end) (confirmed as no typo in reality)
Also, this address would indicate your *.svc file is in the root of that machine - is that really the case?? Normally in IIS, your address will be made up of machine name, virtual directory where the *.svc file resides, and the *.svc file itself, so something like:
http://www.domain.com/ServiceDirectory/Service.svc
I am not sure how you are hosting your service, IIS?
I didn't see anything wrong really in the configuration, other than
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"/>
</security>
If you say that when you type in the address in the IE you see the service, then it is leading me to believe that it is security setting that are wrong. Try removing the security block form the client config file or where ever you have it and see if that works....
If it does, we might have it narrowed it down...
The issue here may have been as simple as the case of true vs True
<proxy usesystemdefault="True" />
I have an application that connects via https to a SOAP-based web service that implements WS-Security. The web service is written in Java, expects a plain text password as well as a properly set timestamp.
After a great deal of googling and experimentation, I can't figure out how to configure my WCF client to interact with this service. In addition to a correct answer, I would also appreciate a link to a tutorial that explains WCF and SOAP well.
My current client's app.config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyServiceSoapBinding" 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="UserName" algorithmSuite="Default" />
</security>
<!--security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security-->
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://p1.my.com/tx/services/MyService"
binding="basicHttpBinding" bindingConfiguration="MyServiceSoapBinding"
contract="My.IMyService" name="MyServiceEndpointPort" />
</client>
</system.serviceModel>
</configuration>
and the client code looks like this:
string response;
try
{
MyService.MyServiceClient svc = new WcfExample.MyService.MyServiceClient();
svc.ClientCredentials.UserName.UserName = "myUser";
svc.ClientCredentials.UserName.Password = "myPass";
response = svc.ping();
lblPingResponse.Text = response;
}
catch (System.ServiceModel.Security.MessageSecurityException mse)
{
lblPingResponse.Text = "MessageSecurityException: " + mse.Message;
}
catch (Exception ex)
{
lblPingResponse.Text = "Exception: " + ex.Message;
}
This code is throwing this exception:
MessageSecurityException "Security
processor was unable to find a
security header in the message. This
might be because the message is an
unsecured fault or because there is a
binding mismatch between the
communicating parties. This can
occur if the service is configured for
security and the client is not using
security."
The WSE 3 version simply requires the following to work:
ServiceUsernameTokenManager.AddUser(userName, password);
UsernameToken token = new UsernameToken(userName, password,
PasswordOption.SendPlainText);
proxy = new _MyServiceWse();
Policy policy = new Policy();
policy.Assertions.Add(new UsernameOverTransportAssertion());
policy.Assertions.Add(new RequireActionHeaderAssertion());
proxy.SetPolicy(policy);
proxy.SetClientCredential(token);
UPDATE:
The request now reaches the server and a response is sent back from the server using this configuration in app.config:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
The client then throws an Exception
"Security processor was unable to find
a security header in the message. This
might be because the message is an
unsecured fault or because there is a
binding mismatch between the
communicating parties. This can
occur if the service is configured for
security and the client is not using
security."
This seems to be because the client sends a Timestamp header, but the service does not return a Timestamp header. This is probably "the right thing to do", but it's not very helpful because there are many web services deployed out there that expect a Timestamp but do not return one.
If there is a way to convince the client to accept this situation I would love to know about it. In the mean time, I'll look into whether I can have the web service changed to return a Timestamp.
Although I realise that you have already marked the answer from Mark_S as correct, you may find the following resolves your issue.
Your error message is addressed in Microsoft Hotfix KB971493: A hotfix that enables WCF to send secured messages and to receive unsecured responses, and to send unsecured messages and to receive secured responses, is available for the .NET Framework 3.5 SP1.
Windows Communication Foundation (WCF) does not have the functionality to send secured messages and then receive unsecured responses, or to send unsecured messages and receive secured responses. The hotfix that is described in this article adds a new enableUnsecuredResponse attribute.
I would be interested to know if this solves your problem.
As for your concrete problem, have a look at a few similar questions on Stackoverflow and elsewhere:
How to authenticate in WCF services in BasicHttpBinding?
http://icoder.wordpress.com/2007/06/22/how-to-setup-a-wcf-service-using-basic-http-bindings-with-ssl-transport-level-security/
Links to useful tutorials and screen casts explaining WCF in great detail: there's the MSDN WCF Developer Center which has everything from beginner's tutorials to articles and sample code.
Also, I would recommend you have a look at the Pluralsight screen casts on WCF - it's an excellent series going from "Creating your first WCF service" and "Creating your first WCF client" all the way to rather advanced topics. Aaron Skonnard very nicely explains everything in 10-15 minutes screencasts - highly recommended!