How could a WCF service become locked? - wcf

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.

Related

SecurityMode.None leads to TimeoutException instead of CommunicationObjectFaultedException

I have a WCF self-hosted service with net.tcp binding.
I need it to be nonsecured with reliable session.
When I configure it to nonsecure all calls to closed service (close, crash, process kill - any reason) lead to timeout exceptions (hang for a minute and timeout). When default (mode = Transport) - I get CommunicationObjectFaultedException at the same moment, seems like infrastructure automatically determines connection break.
How can I get immediate CommunicationObjectFaultedException with nonsecured settings?
Server and client configs are ok. Everything works fine untill I change to nonsecured (of course I change server and client configs).
I've spent many hours to solve the problem, found some similar problems but no answer.
Server config:
<netTcpBinding>
<binding name="TCPBinding" receiveTimeout="Infinite">
<reliableSession enabled="true" inactivityTimeout="00:10:00"/>
<security mode="None">
</security>
</binding>
</netTcpBinding>

timeoutexception or default connection limit on wcf?

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

Browser connects to WCF service but not my WCF client. What can be the reason?

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" />

WCF Service as consumer of another WCF Service

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.

WCF configuration for SOAP plain text password authentication over SSL

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!