Friday, 14 October 2011

Basics of WCF Security – Part 2

Series : Part-1  Part-2  Part-3
In last Article of Basics of WCF Security series, we discussed Core Security Concepts, Transport and Message level security basics and started discussion about Security Settings in WCF.  As usual, this article assumes that you have a fair understanding of basics of WCF and you have at least written or seen a simple WCF application in action.
To refresh it, following is the list of available security settings in WCF
  • Security mode (covered in previous article)
  • Protection level
  • Client and service credentials
  • Impersonation
  • Credential negotiation
  • Secure sessions
  • Authentication and authorization behaviors
In this article we will cover ProtectionLevel :

Protection Levels
Following statements will help in understanding protection level feature of WCF.

1.    Three basic levels of protection exist for any part of a message

Disables message protection.
Signs but does not encrypt the message
Signs and encrypts the message.

2.    When the security mode is set to Transport, the entire message is protected by the transport mechanism. Therefore, setting a separate protection level for different parts of a message has no effect. All application data will be secured according to the capabilities of the transport.

3.    If you select a binding that enables security and you do not set the ProtectionLevel property anywhere on the contract, then default ProtectionLevel for that binding will be applied to all application data (table is given below for default ProtectionLevel for each WCF binding)

4.    If you are using Message security, you can configure message protection to sign but not encrypt each message. This allows you to verify the integrity of a message without the overhead of encryption in case there is no sensitive data requiring protection.

5.    The ProtectionLevel is a way for the developer to set the minimum level that a binding must comply with.

6.    If you set the ProtectionLevel explicitly to either Sign or EncryptAndSign, then you must use a binding with security enabled or an exception will be thrown.

7.    The ProtectionLevel can be set at different scoping levels. There is a hierarchy associated with scoping.

ProtectionLevel at various levels

When programming at the Service Model layer, ProtectionLevel can be set at various levels. The hierarchy is as follows. Attributes at the same level are peers
1.            ServiceContractAttribute level: all messages/faults of a service contract will have same protection level
2.            OperationContractAttribute level: An operation can override the protection level specified at the contract level. So messages/faults of an operation can have different protection requirements.
3.            MessageContractAttribute/FaultContractAttribute level: Individual messages/faults can also specify their own protection level, overriding the one specified at higher level.

How to: Set the ProtectionLevel Property

You can set the protection level by applying an appropriate attribute and setting the property. You can set protection at the service level to affect all parts of every message, or you can set protection at increasingly granular levels, from methods to message parts

     ' Set the ProtectionLevel on the whole service to Sign.
<ServiceContract(ProtectionLevel:=ProtectionLevel.Sign)> _
Public Interface ICalculator

     ' Set the ProtectionLevel on this operation to Sign.
    <OperationContract(ProtectionLevel:=ProtectionLevel.Sign)> _
    Function Add(ByVal a As Double, ByVal b As Double) As Double
End Interface

Public Interface ICalculator
    ' Set the ProtectionLevel on a FaultContractAttribute.
   <OperationContract(ProtectionLevel := ProtectionLevel.EncryptAndSign), _
FaultContract(GetType(MathFault), ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
Function Add(ByVal a As Double, ByVal b As Double) As Double

End Interface
Default ProtectionLevel for Standard Bindings


Protection levels can be set only in code, not in configuration.
If your requirement is to be able to set protection level from config file, then a simple option could be to access the description object model and update the contract protection level there before opening the service host or proxy.
ServiceHost svc = new ServiceHost(typeof(CalculatorService));
svc.Description.Endpoints[0].Contract.ProtectionLevel = GetProtectionLevelFromConfig();
If however, you want to set different protection level for different endpoints, then you have to do some more work.
Specifically you have to create an endpoint behavior, from which you will access the ChannelProtectionRequirements parameter to specify endpoint specific protection requirements. Here is step by step procedure to do this:

We will continue with the other WCF security settings in the next Article.


No comments:

Post a Comment