Lax SecurityHeaderLayout doesn't seem to be allowing timestamp to come last - wcf

I am using the following binding for my service:
<customBinding>
<binding closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<textMessageEncoding messageVersion="Soap12">
<readerQuotas maxDepth="2147483647" maxBytesPerRead="2147483647" maxArrayLength="2147483647"
maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" />
</textMessageEncoding>
<security authenticationMode="CertificateOverTransport" allowInsecureTransport="true" />
<httpTransport maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
</binding>
</customBinding>
This defaults securityHeaderLayout on the security node to Strict, which requires the Timestamp node in the message to come first. I am working with another part of the corporation that does not use WCF, so the individual with whom I am working is trying to use SoapUI to test the service. SoapUI adds the Timestamp node at the end of the message. This can be moved manually, but, apparently, it gets moved back once you sign the node - so you can either have the node come first, or you can have it signed, but not both.
I've tried setting the security node to use Lax or LaxTimestampLast, but it doesn't seem to make a difference:
<security authenticationMode="CertificateOverTransport" allowInsecureTransport="true" securityHeaderLayout="Lax|LaxTimestampLast" />
When I call with my own (WCF) client using LaxTimestampLast, it fails (MessageSecurityException: Signing without primary signature requires timestamp.). Any direction would be greatly appreciated.

I had this same issue recently and I solved it by setting the messageSecurityVersion in my customBinding to a WSSecurity10 version, it had previously had a WSSecurity11 version. Here is my custom binding that works with both my WCF Client and SoapUI:
<customBinding>
<binding name="CustomBinding">
<security authenticationMode="MutualCertificate"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireDerivedKeys="false" securityHeaderLayout="Lax" />
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport />
</binding>
</customBinding>

Related

how to add basicHttpBinding to the custombinding code

I need to authenticate an endpoint using certificate in WCF Config file
I have tried adding with the various authenticationMode setting
but its not working in customBinding
could you please help me to convert the below code to the custom binding
<basicHttpBinding>
<binding name="certBinding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
This is the code i have tried in custom binding
<customBinding>
<binding name="OutbBinding1" closeTimeout="00:02:00" openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:02:00">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="20000000" maxArrayLength="20000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<security authenticationMode="SecureConversation">
<secureConversationBootstrap authenticationMode="AnonymousForCertificate" />
</security>
</binding>
</customBinding>
As we know, if we use the message security of BasicHttpbinding, we should set up the certificate both in the client and the server. In addition, we should also establish a certificate trust relationship between the server and the client.
One more thing needs to note is, different from the authentication mode of the transport layer security, we need to set a default service certificate (non-client certificate, use the trusted server certificates for signing messages) on the client side.
So anyway, the below configuration could achieve the same goal that authenticates the client with a certificate. please refer to the below configuration.
<customBinding>
<binding name="TehRealBinding">
<textMessageEncoding />
<security authenticationMode="MutualCertificate" />
<httpTransport />
</binding>
</customBinding>
Besides, the following document might be useful to you.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/securitybindingelement-authentication-modes
Feel free to let me know if there is anything I can help you.

AddressFilter mismatch at the EndpointDispatcher Error

I have a setup with a client side application that connects to an IIS hosted WCF service with a load balancer in the middle over SSL. The following configuration work when I try to use textMessageEncoding.
Server:
<binding name="customBinding_IRequestService_gzip2">
<textMessageEncoding messageVersion="Soap11" />
<httpTransport maxReceivedMessageSize="2147483647"></httpTransport>
</binding>
Client:
<binding name="customBinding_IRequestService_gzip_secure">
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport maxReceivedMessageSize="2147483647"></httpsTransport>
</binding>
However, I want to use binaryMessageEncoding to take advantage of compression, so I change the configuration to this:
Server:
<binding name="customBinding_IRequestService_gzip2">
<binaryMessageEncoding compressionFormat="GZip">
<readerQuotas maxDepth="64"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
</binaryMessageEncoding>
<httpTransport maxReceivedMessageSize="2147483647"></httpTransport>
</binding>
Client:
<binding name="customBinding_IRequestService_gzip_secure">
<binaryMessageEncoding compressionFormat="GZip">
<readerQuotas maxDepth="64"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
</binaryMessageEncoding>
<httpsTransport maxReceivedMessageSize="2147483647"></httpsTransport>
</binding>
And now I get this error:
System.ServiceModel.EndpointNotFoundException: The message with To
'https://myurl/gzip' cannot be processed at the receiver, due to an
AddressFilter mismatch at the EndpointDispatcher. Check that the
sender and receiver's EndpointAddresses agree.
I tried to incorporate allowInsecureTransport as suggested in some other posts, but the error trail just got worse. What could be the difference between these two encodings? Is it possible that I need to change something on the load balancer, or is this just a matter of getting the WCF configuration right? Thank you.
I implemented this suggestion, and it looks like it is working.
http://blogs.msdn.com/b/morgan/archive/2010/04/15/setting-up-wcf-with-a-load-balancer-using-ssl-in-the-middle.aspx

The remote server returned an error: (413) Request Entity Too Large

I know this is a redundant question, I am getting the error while I am uploading the a file which is more than 100 KB.
The remote server returned an error: (413) Request Entity Too Large.
I am posting the content to a WCF Service (64 bit environment). Am aware this should have been resolved with managing maxReceivedMessageSize and relevant behaviours but unfortunately its not.
Below is my configurations :-
Client
<binding allowCookies="false" bypassProxyOnLocal="false" closeTimeout="00:01:00" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" name="BasicHttpBinding_ICandidateManagementService" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:11:00" textEncoding="utf-8" transferMode="Streamed" useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message algorithmSuite="Default" clientCredentialType="UserName"/>
</security>
</binding>
<behavior name="CandidateBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
<endpoint address="http://localhost:62368/CandidateManagementService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICandidateManagementService" contract="MMJ.ServiceContracts.ServiceContract.ICandidateManagementService" name="BasicHttpBinding_ICandidateManagementService" behaviorConfiguration="CandidateBehavior" />
Service
<services>
<service name="BasicHttpBinding_ICandidateManagementService" behaviorConfiguration="CandidateBehavior">
<endpoint contract="MMJ.ServiceContracts.ServiceContract.ICandidateManagementService" binding="basicHttpBinding" address="" bindingConfiguration="BasicHttpBinding_ICandidateManagementService"/>
</service>
I have seen possibly everything available and still cant solve this issue. have also tried using below configuration, but still no change...
<serverRuntime uploadReadAheadSize="500000000" maxRequestEntityAllowed="500000000"/>
Kindly help!
Service binding Config (its same as client)
<binding allowCookies="false" bypassProxyOnLocal="false" closeTimeout="00:01:00" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" name="BasicHttpBinding_ICandidateManagementService" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:11:00" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="32" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message algorithmSuite="Default" clientCredentialType="UserName"/>
</security>
</binding>
To give more insight below is the fiddlers finding :-
Request Count: 1 Bytes Sent: 85,719 (headers:697; body:85,022)
Bytes Received: 10,129 (headers:254; body:9,875)
At last my problem is resolved after struggling a lot. I had a flaw in my Service config, which was not giving me any runtime or compile time error as it was not even recognizing the config.
My Service Config was :-
<services>
<service name="BasicHttpBinding_ICandidateManagementService" behaviorConfiguration="CandidateBehavior">
<endpoint contract="MMJ.ServiceContracts.ServiceContract.ICandidateManagementService" binding="basicHttpBinding" address="" bindingConfiguration="BasicHttpBinding_ICandidateManagementService"/>
</service>
I have the "Name" property which is not fully qualified name of my service, and thus the configuration I used was not even considered and thus was taking default 65KB for maxReceivedMessageSize.
I have updated it and its working like a charm.
<services>
<service name="MMJ.Services.CandidateManagementService">
<endpoint contract="MMJ.ServiceContracts.ServiceContract.ICandidateManagementService" binding="basicHttpBinding" address="" bindingConfiguration="BasicHttpBinding_ICandidateManagementService"/>
</service>
Also, have a look at this post for more reference. I know this was a silly mistake, and thanks everyone for putting an effort to fix.
You're posting the data to the server, so updating the client settings won't help. The client is not the one receiving the large message, the server is.
Looking at your client endpoint:
Shouldn't the bindingConfiguration be
bindingConfiguration="BasicHttpBinding_ICandidateManagementService"
Instead of
bindingConfiguration="BasicHttpBinding_IAdminService"

Can you test a certificate-secured WCF service with SoapUI?

I have a WCF service that is:
Using the BasicHttpBinding (if you can answer for WsHttpBinding even better!)
Using TransportWithMessageCredential Security
Using X.509 Certificates for Transport and Message security
I would like to be able to test this service with SoapUI.
However, when I attempt to do so it appears that SoapUI signs more of the message than WCF expects, leading to this error (detected in the Application log after enabling ServiceModel auditing):
CryptographicException: Unable to resolve the '#id-100' URI in the signature to compute the digest.
Alternatively, when I use a WsHttpBinding I get the exception:
MessageSecurityException: The message received over Transport security has unsigned 'To' header.
Similar issues have been raised before:
WCF rejects messages with additional signed elements
http://connect.microsoft.com/VisualStudio/feedback/details/481030/wcf-signed-parts
Getting WCF to accept unsigned 'To' Header
This does not strike me as a "Java talking to MS WCF" issue - I have a Java test client working without issue. Likewise, I can use WCFStorm to test the service. However, SoapUI has become a bit of a de facto test standard, particularly for non-Windows consumers.
So, has anyone managed to overcome these issues and test a certificate-secured WCF service using SoapUI?
Thanks
I believe this issue is irresolvable, based on my own testing and a 250 bounty not yielding an answer.
The "web.config" is generated dynamically, but it's effectively matching either of the following bindings:
<wsHttpBinding>
<binding name="WSHttpBinding_ITwoWayAsync" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="250000" maxReceivedMessageSize="250000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="false"
establishSecurityContext="false"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITwoWayAsync" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="250000" maxReceivedMessageSize="250000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
This was impossible with SoapUI and I had to use another tool called WCFStorm.
I had exactly the same issue. I haven't it working with BasicHttpBinding but do have it working with WsHttpBinding. I had the error The message received over Transport security has unsigned 'To' header as well. I created a blogpost for solving this issue. Se the blogpost Connect SoapUI to WCF service certificate authentication for more information.
You have to set the parts in the signature. By default SoapUI signs the whole request but that isn’t the default by WCF so we have to set the parts that we want to sign. So add as Name “To”, Namespace “http://www.w3.org/2005/08/addressing” (this is my namespace but check yours) and set Encode to “Element”. Also check the WS-A panel in your request. Check addressing and set the default "To" checkbox.
I have been able to do this with a custom binding in WCF and a PFX certificate file. I had to use a custom binding because I needed to restrict access to one certificate - which is outside the scope of this question. My certificate pfx file had both the public key and the private key. The private key was password protected. I could not get to this work with any other certificate format.
In SoapUI, I go to File -> Preferences -> SSL Settings:
-->Keystore Name: path_to_PFX_file
-->KeyStore password: your_private_key_password
Here are my web.config settings which are pretty much the same as a basicHttpBinding:
<customBinding>
<binding name="MyServiceBindingConfiguration">
<security authenticationMode="UserNameOverTransport" includeTimestamp="false" requireDerivedKeys="false" securityHeaderLayout="Lax" messageProtectionOrder="SignBeforeEncrypt" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings maxClockSkew="00:30:00" />
<localServiceSettings maxClockSkew="00:30:00" />
<secureConversationBootstrap />
</security>
<textMessageEncoding messageVersion="Soap11">
<readerQuotas maxDepth="32" maxStringContentLength="524288" maxArrayLength="524288" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
Hope this helps.

WCF Service Reference Support Files Not Updating

I have a VS 2010 solution containing a WCF service project and a unit test project. The unit test project has a service reference to the WCF service.
Web.config for the WCF service project sets a number of binding attributes to other-than-default values:
web.config: (Specifically note maxBufferSize="20000000")
<basicHttpBinding>
<binding name="basicHttpBindingConfig" maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
While examining this issue, I came to realize that the unit test project's service reference support files do not contain the values I would expect (i.e. the values configured in the WCF service's web.config):
configuration.svcinfo:
(Specifically note maxBufferSize="65536")
<binding hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" messageEncoding="Text" name="BasicHttpBinding_IBishopService" textEncoding="utf-8" transferMode="Buffered">
<readerQuotas maxArrayLength="16384" maxBytesPerRead="4096" maxDepth="32" maxNameTableCharCount="16384" maxStringContentLength="8192" />
<security mode="None">
<message algorithmSuite="Default" clientCredentialType="UserName" />
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
</security>
</binding>
Deleting and re-creating the service reference or updating the service reference re-creates the files, but I still end up with the same values.
Why?
Update
Here's the app.config of the client
<binding name="BasicHttpBinding_IMyService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="200000000" maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000"
maxBytesPerRead="200000000" maxNameTableCharCount="200000000" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
Same issue here and no solution after half a day messing about with config files... Changing automatically generated files is usually frowned upon, so my feeling says that "there has got to be a better way, Dennis".
UPDATE: I got my problem fixed by removing the name attribute in the binding configuration.
So your current web.config is looking like this
<basicHttpBinding>
<binding name="basicHttpBindingConfig" maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
would become
<basicHttpBinding>
<binding maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
I think you only need to this at the client-side. By removing the name attribute, you essentially change the default basicHttpBinding configuration for your app, as far as I understand it. Credits for this solution here.
Another update: if you name your service configuration correctly (including the namespace) it will pick up the binding configuration. So instead of
<service name="ServiceName">
you need
<service name="My.Namespace.ServiceName">
That is correct behavior. Some information included in binding are specific to only one side of the configuration and both client and server can use completely different values. Also these values are defence against Denial of Service attach so service doesn't want to show them publicly.
Those values affects only processing of incoming messages so service configures how it will handle incoming requests and client configures how it will handle incoming responses. Requests and responses can have different characteristics and different configuration. There is no need for service to be configured to accept 1MB requests if it always receives only few KB requests and returns 1MB responses.
Btw. this is WCF specific feature not related to general web services and because of that there is no standardized way to describe this in WSDL.