Password data in ICredentials
can't be passed from a WCF client to the WCF service in the .NET Framework 4.5
This article helps you resolve the problem where password data in ICredentials
can't be passed from a WCF client to the WCF service.
Original product version: .NET Framework 4.5
Original KB number: 3082119
Symptoms
In a 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
It is a known issue that was introduced in 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 must pass the username and password information to the service independently of the network credential. You can do it by creating an application-defined object to hold the credentials. Then, pass the credentials to a new WCF service method that accepts the object as a method argument. This application-defined object contains sensitive information. We recommend that you send the data over an encrypted connection to the WCF service by using either https transport security or message layer security.
Code that reproduces the issue
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