After experimenting a bit further with WCF performance, it became clear that if we want to increase performance of a WCF service hosted on internet, given that it must support digital signature, where that data is not that sensitive, we can opt for ProtectionLevel.None
for the wsHttpBinding. Following comparison for a typical WCF service shows that using ProtectionLevel.None
, wsHttpBinding is performing quite well:
This result infers to the fact that encrypt and sign operation definitely take additional time in every request and response.
More on ProtectionLevel
Using ProtectionLevel attribute , we can do following–
- We can impose a binding to use certain minimum level of Protection, where the value of
ProtectionLevel
can be– None, Sign, and EncryptAndSign. - We can throttle message protection.
- By default , when security is turned on, value of the
ProtectionLevel
isEncryptAndSign
.
Consequently, we interpret ProtectionLevel
as a mean to enforce consumer of the service to comply with that particular security standard. That is, in the service side we can set the ProtectionLevel = ProtectionLevel.None
, the is, the consumers of the service can use anything above it, such as ProtectionLevel.Sign
, or ProtectionLevel.EncryptAndSign
.
How can we configure it ?
If we are using a transport binding e.g., nettcpBinding
, we can change ProtectionLevel
using the <binding>
configuration–-
<netTcpBinding> | |
<binding name="SignOnlyProectionLevelBindingConfiguration"> | |
<security mode ="Transport" > | |
<transport protectionLevel="Sign"/> | |
</security> | |
</binding> | |
</netTcpBinding> |
However, we cannot specify ProtectionLevel
via declaritive configuration in case of some binding such as– wsHttpBinding
or basicHttpBinding
. In fact, it can only be configured programmatically, as shown below:
[ServiceContract(Namespace="http://www.testservice.protectionlevel.net" , | |
ProtectionLevel = ProtectionLevel.Sign)] | |
public interface ITestService{ } |
So, we cannot change the ProtectionLevel
of these bindings with message level security via configuration after it has been deployed. Furthermore, we can not specify different ProtectionLevel
for different bindings as we need to specify it at the Contract Level in the code. However, there is way to do it which we discuss in the next post.
We can also set the ProtectionLevel
in different levels of WCF Message by specifying it in the following attributes :
Specifying a ProtectionLevel
at the top level have impact at all the levels below, unless it is overridden. For example , we can specify ProtectionLevel
like as follows.
[ServiceContract(Namespace="http://www.testservice.protectionlevel.net" , | |
ProtectionLevel = ProtectionLevel.EncryptAndSign)] | |
public interface ITestService | |
{ | |
[OperationContract(ProtectionLevel= ProtectionLevel.None)] | |
string GetSessionId(); | |
[OperationContract] | |
string GetSessionIdEncrypted(); | |
} |
Even if at the ServiceContract , ProtectionLevel
requirement is EncryptAndSign
, we override it in GetSessionId
by setting the ProtectionLevel
requirement to None
, i.e. the ProtectionLevel
in the lower levels, such as at MessageContract
, MessageHeader
, and MessageBody
will conform to the ProtectionLevel.None
for GetSessionId
, as it is shown in the request and response stream as follows.
On the other hand, GetSessionIdEncrypted
will have encrypted and signed message in the wire, as it is specified at the OperationContract
–
By setting different ProtectionLevel
in different level , we can make our service more efficient and responsive. Lets say , by default our service does not require any encryption and signing at the service contract level, however , service might impose ProtectionLevel.Sign
or ProtectionLevel.EncryptAndSign
to some sensitive operation contract to impose message protection requirement to the client. Seems like a very handy feature, isn’t it? :)
Note that, ProtectionLevel
relies on WS-Addressing to support this kind of different level of ProtectionLevel
in different Level. So, it will result in an unexpected behavior if it is used in Binding what does not support WS-Addressing spec. for instance,BasicHttpBinding
.
In addition, choosing a value for ProctectionLevel does not have any impact in case transport level security as by default it is dependent on Transport Layer Security. For example, in a pretty general case, let’s say , we are running our WCF application over HTTP SSL , it does not matter which ProtectionLevel
we are using as by default it will be encrypt & sign
at the transport layer.
Conclusion
As we observe that ProtectionLevel
is a important attribute with several implications, we must use it with due considerations. Check out the next post, which describe how to specify ProtectionLevel
for multiple endpoints of a service declaratively using a .config file
.
Please feel free leave any comment. Thanks for visiting this blog.
Which tool where you using to snoop soap result for operation?
I don’t remember exactly which one I have used. I suppose you can us Fiddler.