WCF message security with compression - wcf

What is the best practice for compressing the communication of a WCF service having message security enabled, that is not hosted on IIS and uses HTTP as transfer protocol?
In my searching I found implementations made at channel level that apply compression after the message was secured (so the compression is suboptimal).
Can you point me in the right direction?
Or even better: Do you know any WCF compression implementation (working with message security) that is applied before security protocol run?

You can use Microsoft Sample Compression (Microsoft WCF Samples\WCF\Extensibility\MessageEncoder\Compression) and you can use Message Security as TripleDesSha256 algorithm as this config.
<customBinding>
<binding name="customNetTcpBinding">
<transactionFlow transactionProtocol="OleTransactions" />
<reliableSession ordered="true"/>
<Compression innerMessageEncoding="binaryMessageEncoding"
compressionAlgorithm="GZip" />
<security defaultAlgorithmSuite="TripleDesSha256" authenticationMode="SecureConversation" requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true" keyEntropyMode="CombinedEntropy" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature" messageSecurityVersion="Default" requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
<localClientSettings cacheCookies="true" detectReplays="true" replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite" replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00" sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="false" timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="true" issuedCookieLifetime="10:00:00" maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00" negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00" sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="false" maxPendingSessions="128" maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap defaultAlgorithmSuite="TripleDesSha256" authenticationMode="SspiNegotiated" requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true" keyEntropyMode="CombinedEntropy" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature" messageSecurityVersion="Default" requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
<localClientSettings cacheCookies="true" detectReplays="true" replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite" replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00" sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true" timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="true" issuedCookieLifetime="00:15:00" maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00" negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00" sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true" maxPendingSessions="128" maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
</secureConversationBootstrap>
</security>
<tcpTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" connectionBufferSize="8192" hostNameComparisonMode="StrongWildcard" channelInitializationTimeout="00:00:05" maxBufferSize="65536" maxPendingConnections="10" maxOutputDelay="00:00:00.2000000" maxPendingAccepts="1" transferMode="Buffered" listenBacklog="10" portSharingEnabled="false" teredoEnabled="false">
<connectionPoolSettings groupName="default" leaseTimeout="00:05:00" idleTimeout="00:02:00" maxOutboundConnectionsPerEndpoint="10" />
</tcpTransport>
</binding>
</customBinding>

Related

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

I know this question has been asked many time before, but unfortunately none of them resolved my issue.
I have a wcf web service in which i can send a file in form of bytes. If the size of the file is large(around 400 KB) this error comes. For small sized files, this issue is not coming. Following is my server endpoint configuration,
<service behaviorConfiguration="CPServicesBehaviour" name="ConsumerPortalAPI.ReceiveNoteService">
<endpoint address="" binding="customBinding" bindingConfiguration="CustomBinding_IReceiveNoteService" contract="ConsumerPortalAPI.IReceiveNoteService" />
</service>
The binding configuration is,
<binding name="CustomBinding_IReceiveNoteService" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation" requireDerivedKeys="false" includeTimestamp="false" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport" requireDerivedKeys="true" includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</secureConversationBootstrap>
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</security>
<binaryMessageEncoding>
<readerQuotas maxDepth="32767" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="32767" maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
<httpsTransport />
</binding>
The default binding is,
<binding maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation" requireDerivedKeys="false" includeTimestamp="false" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport" requireDerivedKeys="true" includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</secureConversationBootstrap>
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</security>
<binaryMessageEncoding>
<readerQuotas maxDepth="32767" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="32767" maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
<httpsTransport />
</binding>
On my test client side the configuration is,
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_IReceiveNoteService" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation" requireDerivedKeys="false" includeTimestamp="false" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport" requireDerivedKeys="true" includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</secureConversationBootstrap>
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</security>
<binaryMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://cnsportal3.lineartitle.com/cnsAPI/v4/ReceiveNoteService.svc" binding="customBinding" bindingConfiguration="CustomBinding_IReceiveNoteService" contract="CPAction.IReceiveNoteService" name="CustomBinding_IReceiveNoteService" />
</client>
</system.serviceModel>
</configuration>
I tried increasing uploadReadAheadSize of my website to 10485759.
I also tried increasing maxAllowedContentLength of my website to 3000000000.
I checked the web trace on the server through system.diagnostics. Following is the Xml message that is logged in the trace,
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>524326</EventID>
<Type>3</Type>
<SubType Name="Information">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime="2015-01-21T11:01:33.3751197Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{90d52ffb-d886-4164-9d84-e74c04eb79b4}" />
<Execution ProcessName="w3wp" ProcessID="5916" ThreadID="16" />
<Channel />
<Computer>RES-DEV-WEB</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Information">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.GetServiceElement.aspx</TraceIdentifier>
<Description>Get ServiceElement.</Description>
<AppDomain>/LM/W3SVC/5/ROOT/cnsAPI/v4-2-130663116927511157</AppDomain>
<ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/ServiceConfigurationTraceRecord">
<FoundServiceElement>True</FoundServiceElement>
<ConfigurationFileSource>C:\inetpub\wwwroot\cnsportal3.lineartitle.com\ConsumerPortalAPI\v4\web.config</ConfigurationFileSource>
<ConfigurationFileLineNumber>133</ConfigurationFileLineNumber>
<ServiceConfigurationInformation>
<ServiceName>ConsumerPortalAPI.ReceiveNoteService</ServiceName>
<BehaviorConfiguration>CPServicesBehaviour</BehaviorConfiguration>
<Host>
<Timeouts>
<OpenTimeout>00:01:00</OpenTimeout>
<CloseTimeout>00:00:10</CloseTimeout>
</Timeouts>
</Host>
<Endpoints>
<Endpoint>
<Binding>customBinding</Binding>
<BindingConfiguration>CustomBinding_IReceiveNoteService</BindingConfiguration>
<Contract>ConsumerPortalAPI.IReceiveNoteService</Contract>
<ListenUriMode>Explicit</ListenUriMode>
</Endpoint>
</Endpoints>
</ServiceConfigurationInformation>
</ExtendedData>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
This seems that it is able to get the correct Binding Configuration but don't know why it is not using it.
P.S. All bindings are defined under customBinding tag.
Any help in this regard will be highly appreciated. Maybe there is something very small that i am missing here and any one of you can point me to the right direction.
Thanks in advance.
I was able to fix the issue by adding following line in my binding configurations.
<httpsTransport maxReceivedMessageSize="2147483647"/>
The whole binding configuration now looks as,
<binding name="CustomBinding_IReceiveNoteService" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation" requireDerivedKeys="false" includeTimestamp="false" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport" requireDerivedKeys="true" includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</secureConversationBootstrap>
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</security>
<binaryMessageEncoding>
<readerQuotas maxDepth="32767" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="32767" maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
<httpsTransport maxReceivedMessageSize="2147483647"/>
</binding>

The type initializer for 'System.ServiceModel.Diagnostics.TraceUtility' threw an exception

I have developed a console application using C#, to access another API and pull relevant data. It works fine, when I have checked with a small amount of data inputs. While I am doing load testing with huge amount of datas, it throws an exception.
The Exception is:
The type initializer for 'System.ServiceModel.Diagnostics.TraceUtility' threw an exception.
My app.config:
<?xml version="1.0"?>
<configuration>
<commonBehaviors>
<serviceBehaviors>
<serviceTimeouts transactionTimeout="01:55:00"/>
</serviceBehaviors>
</commonBehaviors>
<bindings>
<customBinding>
<binding name="EloquaService"
closeTimeout="00:55:00"
openTimeout="00:55:00"
receiveTimeout="00:55:00"
sendTimeout="01:55:00">
<security defaultAlgorithmSuite="Default"
authenticationMode="UserNameOverTransport"
requireDerivedKeys="true"
securityHeaderLayout="Strict"
includeTimestamp="true"
keyEntropyMode="CombinedEntropy"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings cacheCookies="true"
detectReplays="false"
replayCacheSize="900000"
maxClockSkew="00:05:00"
maxCookieCachingTime="Infinite"
replayWindow="00:05:00"
sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00"
cookieRenewalThresholdPercentage="60"/>
<localServiceSettings detectReplays="false"
issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128"
replayCacheSize="900000"
maxClockSkew="00:05:00"
negotiationTimeout="00:01:00"
replayWindow="00:05:00"
inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00"
sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true"
maxPendingSessions="128"
maxCachedCookies="1000"
timestampValidityDuration="00:05:00"/>
<secureConversationBootstrap/>
</security>
<textMessageEncoding maxReadPoolSize="64"
maxWritePoolSize="16"
messageVersion="Soap11"
writeEncoding="utf-8">
<readerQuotas maxDepth="32"
maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
</textMessageEncoding>
<httpsTransport manualAddressing="false"
maxBufferPoolSize="524288"
maxReceivedMessageSize="65536"
allowCookies="false"
authenticationScheme="Anonymous"
bypassProxyOnLocal="false"
decompressionEnabled="true"
hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true"
maxBufferSize="65536"
proxyAuthenticationScheme="Anonymous"
realm=""
transferMode="Buffered"
unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true"
requireClientCertificate="false"/>
</binding>
<binding name="EmailServiceEndpoint"
closeTimeout="00:55:00"
openTimeout="00:55:00"
receiveTimeout="00:55:00"
sendTimeout="01:55:00">
<security defaultAlgorithmSuite="Default"
authenticationMode="UserNameOverTransport"
requireDerivedKeys="true"
securityHeaderLayout="Strict"
includeTimestamp="true"
keyEntropyMode="CombinedEntropy"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings cacheCookies="true"
detectReplays="false"
replayCacheSize="900000"
maxClockSkew="00:05:00"
maxCookieCachingTime="Infinite"
replayWindow="00:05:00"
sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00"
cookieRenewalThresholdPercentage="60"/>
<localServiceSettings detectReplays="false"
issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128"
replayCacheSize="900000"
maxClockSkew="00:05:00"
negotiationTimeout="00:01:00"
replayWindow="00:05:00"
inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00"
sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true"
maxPendingSessions="128"
maxCachedCookies="1000"
timestampValidityDuration="00:05:00"/>
<secureConversationBootstrap/>
</security>
<textMessageEncoding maxReadPoolSize="64"
maxWritePoolSize="16"
messageVersion="Soap11"
writeEncoding="utf-8">
<readerQuotas maxDepth="32"
maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
</textMessageEncoding>
<httpsTransport manualAddressing="false"
maxBufferPoolSize="524288"
maxReceivedMessageSize="65536"
allowCookies="false"
authenticationScheme="Anonymous"
bypassProxyOnLocal="false"
decompressionEnabled="true"
hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true"
maxBufferSize="65536"
proxyAuthenticationScheme="Anonymous"
realm=""
transferMode="Buffered"
unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true"
requireClientCertificate="false"/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://secure.eloqua.com/API/1.2/service.svc"
binding="customBinding"
bindingConfiguration="EloquaService"
contract="EloquaService.EloquaService"
name="EloquaService"/>
<endpoint address="https://secure.eloqua.com/API/1.2/ExternalActionService.svc"
binding="customBinding"
bindingConfiguration="EmailServiceEndpoint"
contract="EloquaProgramService.ExternalActionService"
name="EmailServiceEndpoint"/>
</client>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
How do I solve this problem?
The issue has been overcome. Probably I was having two app.config files. One is from the service reference and another one from my application. Both were having the same code. I just removed the below code from my appl.config which is placed in my application. Now it is not throwing the above exception.
<commonBehaviors>
<serviceBehaviors>
<serviceTimeouts transactionTimeout="01:55:00"/>
</serviceBehaviors>
</commonBehaviors>
This happened to me just now. I thought of sharing, even though it is very silly.
Here is what I did
I added reference to WCF service in a console application.
I added a key-value pair value in config without it being inside appSettings section in the config. In my haste to test the service I ran my console application and got the exact same error.
On going into the error details, I figured it was because of invalid config entries in my config.
Once I added the key value pair inside appSettings section, it worked. I know it's silly, but still it happened to me. :).
I had similar exception and problem was
1) having two config files and had similar settings (web.config in Web layer / app.config in Service Layer-we were calling external service)
2) invalid section in web.config (log4net config section)
Visual studio did not show any error for no#2 as its looks valid section for VS but at run time it was throwing error. Removed app.config in Service layer and it resolved issue.

WCF SOAP Error for Larger Requests

I need to download a few hundred thousand entities from a 3rd party hosted web service. The web service allows me to pull down up to 2,000 entities per web service call, but in practice I have only been able to pull down 50-75 entities at a time because of intermittent errors I receive when I call more records. I'm trying to determine if the problem is due to a setting I need to adjust on my side or if the problem is with the 3rd party web service provider. Here's the error I receive:
An error occurred while receiving the HTTP response to
https://some.vendor.com/API/SomeService.svc. This could be due to the
service endpoint binding not using the HTTP protocol. This could also
be due to an HTTP request context being aborted by the server
(possibly due to the service shutting down). See server logs for more
details.
The following is a copy of my application configuration settings for binding the web service:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="SomeService">
<security defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport"
requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings cacheCookies="true" detectReplays="false"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap />
</security>
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Streamed" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" requireClientCertificate="false" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://secure.Some.com/API/1.2/Service.svc"
binding="customBinding" bindingConfiguration="SomeService"
contract="SomeService.SomeService" name="SomeService" />
</client>
</system.serviceModel>
As you can see in the application configuration binding, I increased the maxBufferPoolSize, maxReceivedMessageSize, and maxBufferSize to 2147483647. I also changed the transferMode to Streamed.
There is another important setting that can be set by adding a behavior:
<behaviors>
<endpointBehaviors>
<behavior name="SomeBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
</behaviors>
Then, update your endpoint:
<client>
<endpoint address="https://secure.Some.com/API/1.2/Service.svc"
binding="customBinding" bindingConfiguration="SomeService"
contract="SomeService.SomeService" name="SomeService"
**behaviorConfiguration="SomeBehavior"**/>
</client>

WCF service - security in SOAP header

I’m trying to use a wcf service with UserNameOverTransport binding. I want my Soap header to look like this:
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-14430313" xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>USERNAME</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username- token-profile-1.0#PasswordText">PASSWORD</wsse:Password>
<wsse:Nonce>OquGazmuMMHFrdeRQZGpkA==</wsse:Nonce>
<wsu:Created>2009-08-25T19:17:07.369Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
My SOAP looks like this:
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis- 200401-wss-wssecurity-secext-1.0.xsd"><u:Timestamp u:Id="_0"><u:Created>2011-07-
29T10:38:58.452Z</u:Created><u:Expires>2011-07-
29T10:43:58.452Z</u:Expires></u:Timestamp><o:UsernameToken u:Id="uuid-63332174-a7b4-
4833-bd2e-32d0c0820f42-1"><o:Username>USERNAME</o:Username><o:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-
1.0#PasswordText">PASSWORD</o:Password></o:UsernameToken></o:Security>
I have used
proxyclient.ClientCredentials.UserName.UserName = "USERNAME"
proxyclient.ClientCredentials.UserName.Password = "PASSWORD"
to insert username and password into the SOAP header, but I also need to insert wsse:Nonce and wsu:Created, how can I do that? And what is the diferense between using .ClientCredentials.UserName.UserName and ChannelFactory.Credentials.UserName.UserName?
And how can I get the tags correct, wsse instead of o?
I’m using VS 2010 and VB.NET, and UserNameOverTransport binding. Do I have to install wse 3.0?
My app.config file looks like this:
<customBinding>
<binding name="CustomBinding_IIntermediaryInboundExternal">
<security defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport"
requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings cacheCookies="true" detectReplays="false"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap />
</security>
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Default" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
<endpoint address="https://myendpointadress.svc"
binding="customBinding" bindingConfiguration="CustomBinding_mysevice"
contract="myendpoint"
name="CustomBinding_myendpoint" />
I hope someone can help me with this! Thanks a lot!!
Standard WCF UserNameToken profile implementation in WCF doesn't use Nonce and Created = there is no way to force WCF to include them. Prefix doesn't matter that is just symbolic name defined in wrapper element and all correct XML parse implementations should work with both wsse or o.
The reason why WCF doesn't use Nonce and Created elements is because these elements should be used with #PasswordDigest type (which is not supported by WCF). Using them with #PasswordText doesn't make too much sense.
If your service requires Nonce and Created you must implement your own token instead of using standard WCF's user name implementation. Here is example of building whole new UserNameToken profile implementation to support #PasswordDigest. It adds Nonce and Created elements as well.

WCF: programatically configuring the service with certificate

Here's the whole issue: I want to create WCF dll to access WCF services.... the only issue is, when I use the WCF DLL config file with an application that has it's OWN app.config file, the WCF DLL app.config file gets ignored.......
I figure one way to fix this problem is to translate my app.config to code, but unfortunately I don't know what I am doing.
If you look at the app.config file below, you can also see that I use a certificate with an encoded value, which has made it more difficult for me to translate because like I said before I have no idea what I am doing, this is kind of a "learn as you go approach" for me.
Does anyone have any idea of how to accomplish either being able to use the app.config as is, instead of the WCF service accessing the APPLICATION's app.config?
OR
Does anyone have an article, tool or advice on how to translate the following app.config to C#?
any information would be fantastic..... Thanks, in advance.
<system.serviceModel>
<bindings>
<customBinding>
<binding name="customBindingHTTP">
<security authenticationMode="SecureConversation">
<localClientSettings maxClockSkew="23:30:00" />
<secureConversationBootstrap authenticationMode="UserNameForSslNegotiated">
<localClientSettings maxClockSkew="23:30:00" />
</secureConversationBootstrap>
</security>
<binaryMessageEncoding maxReadPoolSize="20000000" maxWritePoolSize="20000000"
maxSessionSize="20000000">
<readerQuotas maxDepth="20000000" maxStringContentLength="20000000"
maxArrayLength="20000000" maxBytesPerRead="20000000" maxNameTableCharCount="20000000" />
</binaryMessageEncoding>
<httpTransport maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000"
maxBufferSize="20000000" useDefaultWebProxy="false" />
</binding>
<binding name="CustomBinding_ITestService">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
<localClientSettings cacheCookies="true" detectReplays="true"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="true" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap defaultAlgorithmSuite="Default"
authenticationMode="UserNameForSslNegotiated" requireDerivedKeys="true"
securityHeaderLayout="Strict" includeTimestamp="true" keyEntropyMode="CombinedEntropy"
messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
<localClientSettings cacheCookies="true" detectReplays="true"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="true" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
</secureConversationBootstrap>
</security>
<binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
maxSessionSize="2048">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binaryMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://xx.xx.xxx.xxx:xxxx/TestService/custom"
behaviorConfiguration="ClientCertificateBehavior" binding="customBinding"
bindingConfiguration="customBindingHTTP" contract="ServiceReference1.ITestService"
name="CustomBinding_ITestService">
<identity>
<certificate encodedValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
The code below should be a good starting point for what you require. I've filled in a handful of the properties that I saw in your app.config and set them appropriately.
CustomBinding endpointBinding = new CustomBinding();
SymmetricSecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameForSslBindingElement();
securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
securityElement.LocalClientSettings.MaxClockSkew = new TimeSpan(23, 30, 0);
endpointBinding.Elements.Add(securityElement);
endpointBinding.Elements.Add(new BinaryMessageEncodingBindingElement());
endpointBinding.Elements.Add(new HttpsTransportBindingElement());
As for the certificate... Once you have a WCF service host object you can add the certificate like so:
host.Credentials.ServiceCertificate.Certificate = cert;
Also you can put your dll's app.config file contents into the caller app's app.config file.