No se pueden pasar datos de contraseñas de ICredentials un cliente de WCF al servicio WCF en .NET Framework 4,5

Este artículo le ayuda a resolver el problema por el que no se pueden pasar datos de contraseñas de ICredentials un cliente de WCF al servicio de WCF.

Versión del producto original:   .NET Framework 4,5
Número de KB original:   3082119

Síntomas

En un cliente de WCF, se crea una ICredentials interfaz nueva a partir de la NetworkCredential clase con el nombre de usuario y la contraseña que se especifican. A continuación, se realiza una llamada a un método de contrato WCF que toma ICredentials como argumento. Observa que después de convertir el ICredentials que se recibe en el servicio WCF de nuevo a una credencial de red, la Password propiedad contiene una cadena vacía. Sin embargo, la Username propiedad sigue conteniendo un valor correcto y válido.

Causa

Se trata de un problema conocido que se introdujo en Microsoft .NET Framework 4,0, cuando se agregó una nueva propiedad SecurePassword a la NetworkCredential clase. Esta propiedad sobrescribe la cadena de contraseña original cuando la SecurePassword propiedad se deserializa en el lado del servicio. La SecurePassword propiedad es de tipo SecureString . Por diseño, no se serializa ni se envía. Sin embargo, sobrescribe la cadena de contraseña original con un valor vacío. Este comportamiento también se debe a su diseño.

Solución

Para solucionar este problema, debe pasar la información de nombre de usuario y contraseña al servicio independientemente de la credencial de red. Puede hacerlo creando un objeto definido por la aplicación para que contenga las credenciales. A continuación, pase las credenciales a un nuevo método de servicio WCF que acepte el objeto como un argumento de método. Este objeto definido por la aplicación contiene información confidencial. Le recomendamos que envíe los datos a través de una conexión cifrada al servicio WCF mediante la seguridad de transporte https o la seguridad de la capa de mensaje.

Código que reproduce el problema

En el ejemplo siguiente se muestra un servicio WCF que reproduce el problema. El servicio WCF tiene el siguiente contrato:

[ServiceContract]
[ServiceKnownType(typeof(NetworkCredential))]
public interface IService
{
    [OperationContract]
    string GetData(ICredentials value);
}

Un cliente está usando el servicio de la siguiente manera:

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

Mediante el uso de Visual Studio y la configuración de un punto de interrupción en el servicio, el value.Password estará vacío. Cuando se examinan las ventanas locales de Microsoft Visual Studio, se ve el texto siguiente:

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