Implementing Reliable Session in WCF
Implementing Reliable Session in WCF
By : Kasim Wirama, MCDBA, MVP SQL Server
The potential problem in distributed environment is the reliability of message delivery. Message could be lost in the middle for transport process between client-server, or message could arrive more than once to the destination or messages come to destination not in same order when messages are sent from source. Other issue is source doesn’t know whether the message is received by destination or not.
Another issue is how to secure message during routing from source to destination. They could be intercepted, modified in the middle of delivery, and could be resent several times (such as flooding to server until server busy to process same message until server shows denial of service symptom). This kind of attack is called replay attack. Fortunately, by default, WCF recognize this attack and it can handle this attack.
To address unreliable message delivery, OASIS organisation proposes WS-ReliableMessaging with interoperable protocol. And to address message security, OASIS proposes WS-SecureConversation that is build on WS-security (WS-security itself is one of pillars in WS-* specifications).
It is very easy to set up reliable session and securing service from reply attack with just changes in application configuration file with Microsoft Service Configuration Editor program.
Setting up reliable session
You need to establish same characteristic required for reliable session both in WCF service and WCF client. To ensure client establish session, session mode should be specified in service contract. Some protocol bindings support reliable session, others don’t. The protocols that support reliable session is wsHttpBinding, wsDualHTTPBinding, netTcpBinding, wsFederationHTTPBinding. msmqIntegrationBinding, netMsmqbinding implement their own reliable session method. The others that don’t support reliable session are basicHttpBinding, netNamedPipeBinding, netPeerTcpBinding.
Here I show you example how to setup reliable session with netTcpBinding.
At WCF service
Edit app.config with Service Configuration Editor program, in Binding folder create new netTcpBinding, on Binding tab, set Enabled and Ordered at ReliableSessionProperties group to true, make sure TransferMode is Buffered.
Create new endpoint, fill new endpoint name, specify endpoint address (for example: net.tcp://localhost:9003/Service/Service.svc, set Binding property to netTcpBinding, BindingConfiguration to the tcpBinding you have configured on previous paragraph. Set contract by browsing to assembly that contains service contract.
At WCF client
Edit app.config with Service Configuration Editor program. Set up binding properties, similar with configuring property at WCF service. You create client tcp endpoint, similar with configuring new tcp endpoint of WCF service. The tricky part is when you specify contract, you should specify contract on client’s assembly that contains contract service. Usually contract service could be found in proxy generated from WCF service.
Securing service from reply attack.
By default, WCF can detect reply attack, for this sample, I would like to set up WCF based on WS-secure conversation. You can set WS-secure conversation explicitly instead of using built-in WS-secure conversation in standard WCF binding. For this sample, I would show you how to create custom binding that implements WS-secure conversation.
At WCF Service
Edit app.config with Service Configuration Editor program, create new custom binding by right clicking Bindings folder. By default, custom binding will create 2 stack elements : textMessageEncoding and httpTransport, remove httpTransport, and add tcpTransport, add also security. If you would include transaction support and reliableSession, include them in stack element. Order stack from 1 to 5 is transactionFlow, reliableSession, security, textMessageEncoding and TcpTransport, on security item, set AuthenticationMode property to SecureConversation. In service tab (in WCF client you choose Client tab), adjust value ReplayCacheSize, MaxClockSkew, and ReplayWindow, usually these values of three properties is just fine, if you set ReplayCacheSize too low, more possibility your WCF service will be easier to get replay attack because WCF service doesn’t have enough cache to save items that are not replay attack items.
Bind this custom binding to new custom endpoint of the service.
At WCF Client
Configuration steps are similar to WCF service, except you bind custom binding to client endpoint instead of service endpoint. Give custom endpoint name that will be input for instantiating proxy.
At main method of Program.cs, set proxy instance with new custom endpoint name, and run your WCF client.
There must be a trade-off if you implement reliable session and secure conversation from replay attack. The trade-off is that message size will be bigger and requires more extra protocol in each communication between WCF service and WCF client because there contains more information about ordering, message acknowledge from both sides, identifier generated from both sides that should be included in each message sent to target, nonces (random, unique, signed, time-stamped identifier) to address replay attack issue.