Transfer large data object via WCF client to WCF server - c#

I'm trying to transfer a large data object from a WinForms client via WCF.
When the client tries to get the object from the server, the transfer succeeds; but
when the client tries to send the object to the server, I get an error!!
The error is:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException
webException, HttpWebRequest request, HttpAbortReason abortReason)
at
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan
timeout) at
System.ServiceModel.Channels.RequestChannel.Request(Message message,
TimeSpan timeout) at
System.ServiceModel.Channels.ClientReliableChannelBinder1.RequestClientReliableChannelBinder1.OnRequest(TRequestChannel
channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
at
System.ServiceModel.Channels.ClientReliableChannelBinder1.Request(Message
message, TimeSpan timeout, MaskingMode maskingMode) at
System.ServiceModel.Channels.ClientReliableChannelBinder1.Request(Message
message, TimeSpan timeout) at
System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message
message, TimeSpan timeout) at
System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message
message, TimeSpan timeout) at
System.ServiceModel.Channels.ServiceChannel.Call(String action,
Boolean oneway, ProxyOperationRuntime operation, Object[] ins,
Object[] outs, TimeSpan timeout) at
System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage
methodCall, ProxyOperationRuntime operation) at
System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage
message)
I try to add the behavior attribute DataContractSerializer and set it to max value. The transferring works only one way - from the server to the client! On the other side - from the client to the server it doesn't work!
Thank you for your help.

Try adding the following parameters to your web.config file (adapt the value for your case):
<behaviors>
<serviceBehaviors>
<behavior name="">
<dataContractSerializer maxItemsInObjectGraph="6553600"/>
</behavior>
</serviceBehaviors>
</behaviors>
...
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="512000000" />
</requestFiltering>
</security>
</system.webServer>

There are several settings that control the max size of a message
MaxBufferSize
MaxReceivedMessageSize
MaxStringContentLength
See: http://geekswithblogs.net/niemguy/archive/2007/12/11/wcf-maxstringcontentlength-maxbuffersize-and-maxreceivedmessagesize.aspx

Related

WCF - Cannot find a token authenticator for X509SecurityToken

I'm trying to call a 3rd party webservice and I've gotten to the point where I can actually see a response from the server in the Service Trace Viewer. However, I keep getting an exception from .NET:
Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type.
Tokens of that type cannot be accepted according to current security settings.
My app.config looks like this (Thumbprints replaced by placeholders):
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="OteBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
<defaultCertificate findValue="<ThumbprintPlaceholder1>" x509FindType="FindByThumbprint" storeLocation="CurrentUser" storeName="TrustedPeople"/>
</serviceCertificate>
<clientCertificate findValue="<ThumbprintPlaceholder2>" x509FindType="FindByThumbprint"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="MyBinding">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="CertificateOverTransport"
messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
requireSecurityContextCancellation="false"
enableUnsecuredResponse="true"
allowSerializedSigningTokenOnReply="true">
</security>
<httpsTransport maxBufferPoolSize="2147483646" maxBufferSize="2147483646" maxReceivedMessageSize="2147483646" requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://example.com:1443/xxx/someService/"
binding="customBinding" bindingConfiguration="MyBinding" behaviorConfiguration="OteBehavior"
contract="ReportGasService.ReportGas" name="ReportGasEndpoint" />
</client>
Now, I've tried everything I could find regarding this exception.
Setting authenticationMode to MutualCertificate: Server responds 404
Setting allowSerializedSigningTokenOnReply: No change
The reponse from the server contains:
<ds:KeyInfo Id="KI-1DE4B371623632132E1468838210413180294">
<wsse:SecurityTokenReference wsu:Id="STR-1DE4B271123632132E1468838710413180295">
<wsse:Reference URI="#X509-1DE4B271523632132E1468833710413180293" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"></wsse:Reference>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
Can I add the x508SecurityToken handler somewhere or otherwise ignore this error (is it safe to do so)
Exception Stack Trace:
Server stack trace:
at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver, IList`1 allowedTokenAuthenticators, SecurityTokenAuthenticator& usedTokenAuthenticator)
at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlDictionaryReader reader, Int32 position, Byte[] decryptedBuffer, SecurityToken encryptionToken, String idInEncryptedForm, TimeSpan timeout)
at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader)
at System.ServiceModel.Security.StrictModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Does the above mean that it is serverside?
I found the solution:
Change authenticationMode="CertificateOverTransport" to authenticationMode="MutualCertificate"
Use MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10
In the generated client, add ProtectionLevel = ProtectionLevel.Sign to the ServiceContractAttribute. This avoids having the body encrypted.
I'm still not all the way through, but I believe it is merely a matter of getting the right certificate from the provider.
For others, here is how I create my proxy:
var binding = new BasicHttpsBinding();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var address = new EndpointAddress(new Uri("https://xxx/yyy/someService/"));
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
var securityElement = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, true);
securityElement.IncludeTimestamp = true;
var customBinding = new CustomBinding(binding);
customBinding.Elements.Insert(0, securityElement);
var client = new ReportGasClient(customBinding, address);
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "BCC3929F9C115D4BCA1C697E2557B7FC7D6C8C8C");
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "87C3B5EE3913937459D2FFBF105ADBD1A578E823");
Please note I set the ValidationMode to None only in the sandbox environment. This should never be used in production.
Your values for findValue attribute are both incorrect. You should be putting the specific thumbprint value for the corresponding client-side certificates in the app.config.
You can view the certificate thumbprint values via the Certificates MMC add-in.
I would also double-check that client-side X509 certificates are required as normally, they are only required for server-side operation.

Binding error (binding mismatch?, security mismatch?) when calling a web service

Please forgive my lack of experience with WCF, but I'm having an issue with it that I am having some difficulty understanding.
Another organization at the company I work at has created a web service for me to consume. I believe I have correctly added a Service Reference to my project using the WSDL they provided. Their web service is based off of an Oracle API that I know very little of, I'm not an Oracle developer.
Here is the code I used to make use of the service reference:
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
basicHttpBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress epa = new EndpointAddress("https://MYENDPOINT.URL");
MyServiceReference.SERVICENAME_PortTypeClient port = new MyServiceReference.SERVICENAME_PortTypeClient(basicHttpBinding, epa);
port.ClientCredentials.UserName.UserName = SERVICE_U;
port.ClientCredentials.UserName.Password = SERVICE_P;
SOAHeader header = new SOAHeader();
header.Responsibility = SERVICE_RESPONSIBILITY;
InputParameters2 ip2 = new InputParameters2();
ip2.param1 = "abcd";
ip2.param2 = "1234"
OutputParameters2 output = port.WEB_SERVICE_FUNCTION(header, ip2);
Here the information in my Web.Config file regarding the binding information:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SERVICENAME_Binding">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://MYENDPOINT.URL"
binding="basicHttpBinding" bindingConfiguration="SERVICENAME_Binding"
contract="MyServiceReference.SERVICENAME_PortType"
name=SERVICENAME_Port" />
</client>
</system.serviceModel>
When the call is made to the service I get the following error:
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.
With the following stacktrace:
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at MyProject.MyServiceReference.SERVICE_NAME_PortType.WEB_SERVICE_FUNCTION(WEB_SERVICE_FUNCTIONRequest request)
at MyProject.MyServiceReference.SERVICE_NAME_PortTypeClient.MyProject.MyServiceReference.SERVICE_NAME_PortType.WEB_SERVICE_FUNCTION(WEB_SERVICE_FUNCTIONRequest request) in c:\MyProject\Service References\MyServiceReference\Reference.cs:line 981
at MyProject.MyServiceReference.SERVICE_NAME_PortTypeClient.WEB_SERVICE_FUNCTION(SOAHeader SOAHeader, InputParameters2 InputParameters) in c:\MyProject\Service References\MyServiceReference\Reference.cs:line 988
at MyProject.MyClass.MyFunction(String inputParam) in c:\MyProject\MyClass.asmx.cs:line 160
After looking at the stack trace, it appears that the verification of the response may be the issue which lead me to believe that it may have to do with a timestamp issue that others have had (ex. http://blog.latamhub.com/?p=78) may be the issue, but when I try to add the includeTimestamp="true" attribute to the security tag in the Web.Config file, VS2012 reports that the includeTimestamp attribute is not allowed. Not quite certain what is going on here or what else to check. Any help or ideas are greatly appreciated.
Thanks.
EDIT (2013-05-30):
Tried the following custom binding with the includeTimestamp set to true and false with no success:
<customBinding>
<binding name="SERVICENAME_Binding">
<security
includeTimestamp="true"
/>
</binding>
</customBinding>

trying to consume wcf service but I think my web.config file is incorrect

I am having try trying to consume a service. I am trying to deploy it to a server and consume it however I get this error. I have created a web application and added a wcf service. I am getting this
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at IBusinessV1.CheckForUpdate(String currentVersion)
at BusinessV1Client.CheckForUpdate(String currentVersion)
Is there something wrong with my config?
<system.serviceModel>
<services>
<service name="SP.WebWCF.Business_v1">
<endpoint
address="https://services.mydomain.com"
binding="basicHttpBinding"
bindingConfiguration=""
contract="SP.WebWCF.IBusiness_v1"
listenUri="/" isSystemEndpoint="true" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Ok, so your did show the server config, but you never really told us what the error is - you show the stack trace - but not the error message.....
Anyway, looking at your service config, one thing seems a bit odd - your service address:
address="https://services.mydomain.com"
binding="basicHttpBinding"
Typically this would either be something like
address="https://services.mydomain.com/MyServiceVirtualDir/MyService.svc"
if you're hosting your service inside IIS, or something like
address="https://services.mydomain.com/MyService"
if you're self-hosting in a Windows NT service or something.
Can you double-check your address - are you 100% sure it's correct??
Update: also, you're using https://, however, you're not showing any security-settings in your service config. Just for test: can you invoke your service when you change the service address in the config to just http:// ??

TimoutException occurs over a network but not locally

I have a program with three WCF services and when I run them locally (i.e: Server and Clients are all on localhost) everything works. However when I test them across a network I get a TimoutException on two services but not the other. I've disabled the firewalls on all the machines involved in the test. I can both ping the server and access the wsdl "You have created a service" webpage from the client
The service that works uses a BasicHttpBinding with streaming and the two which don't work use WSDualHttpBinding. The Services that use WSDualHttpBinding both have CallbackContracts. I apologise for the vagueness of this question but I'm not really sure what code to include or where to even start looking for the solution to this.
Non-working bindings:
public static Binding CreateHTTPBinding()
{
var binding = new WSDualHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Mtom;
binding.MaxBufferPoolSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.Security.Mode = WSDualHttpSecurityMode.None;
return binding;
}
Exception Stack Trace:
Unhandled Exception: System.TimeoutException: The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
Server stack trace:
at System.ServiceModel.Channels.ReliableRequestor.ThrowTimeoutException()
at System.ServiceModel.Channels.ReliableRequestor.Request(TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableSession.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableDuplexSessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at IDemeService.Register()
at DemeServiceClient.Register()
at DemeClient.Client.Start()
at DemeClient.Program.Main(String[] args)
You may enable System.Net tracing on both sides and read about the Timeout exception.
http://support.microsoft.com/kb/947285
You are using a DualHttpBinding. What this means is that you are setting up a duplex channel, where server can send messages (not response message, but a incoming message) to client. But you haven't setup a clientBaseAddress where client will be listening for incoming messages from server. This is what is causing this issue. from http://msdn.microsoft.com/en-us/library/system.servicemodel.wsdualhttpbinding.aspx:
This binding requires that the client has a public URI that provides a callback endpoint for the service. This is provided by the ClientBaseAddress. A dual binding exposes the IP address of the client to the service. The client should use security to ensure that it only connects to services it trusts.

Anyone used a WCF client with SSRS a web service?

I'm having issues using the WcfTestClient with a SSRS report asmx service. Has anyone gotten it to work?
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'.
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest request, HttpWebResponse response, WebException responseException, HttpChannelFactory factory)
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at ReportingService2005Soap.ListSubscriptions(ListSubscriptionsRequest request)
at ReportingService2005SoapClient.ReportingService2005Soap.ListSubscriptions(ListSubscriptionsRequest request)
I figured it out, with the help of another post, which I can't find now.
I used the svcutil utility to create the service/data contracts and provide a client. Then set the binding as follows.
<basicHttpBinding>
<binding name="SsrsSoapBinding" >
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>

Categories

Resources