Password data in ICredentials can't be passed from a WCF client to the WCF service in the .NET Framework 4.5

Symptoms
In a Windows Communication Foundation (WCF) client, you create a new ICredentials interface from the NetworkCredential class by using the username and password that are specified. Then, you make a call to a WCF contract method that takes ICredentials as an argument. You find that after you cast the ICredentials that are received in the WCF service back to a network credential, the Password property holds an empty string. However, the Username property is still holding a valid, correct value. 
Cause
This is a known issue that was introduced in the Microsoft .NET Framework 4.0 when a new property, SecurePassword, was added to the NetworkCredential class. This property overwrites the original password string when the SecurePassword property is deserialized on the service side. The SecurePassword property is of type SecureString. By design, it isn't serialized and sent. However, it overwrites the original password string by using an empty value. This behavior is also by design.
Resolution
To fix this issue, you have to pass the username and password information to the service independently of the network credential. You can do this by creating an application-defined object to hold the credentials and to pass the credentials to a new WCF service method that accepts the object as a method argument. Because this application-defined object contains sensitive information, we recommend that the data be sent over an encrypted connection to the WCF service by using either https transport security or message layer security.
More information
The following example shows a WCF service that reproduces the issue. The WCF service has the following contract:

[ServiceContract]
[ServiceKnownType(typeof(NetworkCredential))]
public interface IService
{

    [OperationContract]
    string GetData(ICredentials value);
}

A client is using the service as follows:

iCredService.ServiceClient svcClient = new iCredService.ServiceClient();
ICredentials iCred = new System.Net.NetworkCredential("ABC", "1234");
string outCome = outCome = svcClient.GetData(iCred);

Using Visual Studio and setting a breakpoint at the service the value. Password will be empty. When you examine the Microsoft Visual Studio locals windows, you see the following text:

-   value {System.Net.NetworkCredential} System.Net.ICredentials {System.Net.NetworkCredential}
-      [System.Net.NetworkCredential] {System.Net.NetworkCredential} System.Net.NetworkCredential
 Domain  "" string
 Password "" string
+ SecurePassword {System.Security.SecureString} System.Security.SecureString
 UserName "ABC" string
ICredentials NetworkCredential SecurePassword WCF
Properties

Article ID: 3082119 - Last Review: 08/28/2015 19:13:00 - Revision: 1.0

Microsoft .NET Framework 4, Microsoft .NET Framework 4.5, Windows Communication Foundation 4, Windows Communication Foundation 4.5

  • KB3082119
Feedback