2009-11-12 13 views
8

He estado trabajando con WCF los últimos dos días y me fue muy bien con el servidor y el cliente en mi máquina de desarrollo. Ahora que estoy tratando de hacer algunas pruebas distribuidas con el cliente en otra máquina de la red, comencé a tener problemas. En este momento el error que estoy consiguiendo es:Cómo desactivar la seguridad programáticamente en WCF

El mensaje con Acción 'http://tempuri.org/IWindowUpdateContract/UpdateWindowFrames' no pueden ser procesados ​​en el receptor, debido a una falta de coincidencia en el ContractFilter EndpointDispatcher. Esto puede deberse a una discrepancia en el contrato (acciones no coincidentes entre el emisor y el receptor) o una falta de correspondencia vinculante/de seguridad entre el emisor y el receptor. Verifique que el remitente y el receptor tengan el mismo contrato y el mismo enlace (incluidos los requisitos de seguridad, por ejemplo, Mensaje, Transporte, Ninguno).

Como esto ya es una experiencia masiva de aprendizaje (no he hecho ninguna interacción remota, RPC, y otros antes) quiero seguir el desarrollo de la herramienta de aprendizaje y volver a la seguridad cuando haya terminado (no tengo ninguna intención de construir cualquier cosa que realmente se use sin las mejores prácticas de seguridad adecuadas).

Notas:

  • que no tienen un archivo de configuración para la configuración de WCF - Estoy haciendo todo mediante programación.
  • Mi red no es parte de un dominio, por lo que la configuración de seguridad predeterminada no funcionaba para mí (usando net.tcp).
  • Estoy usando '.Net 3.5'.

Mi servidor se crea de esta manera:

var svh = new ServiceHost(_serviceImplementation); 

    var binding = new NetTcpBinding(); 

    binding.ReaderQuotas.MaxArrayLength = 2000000; 
    binding.Security.Mode = SecurityMode.None; 
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None; 
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; 
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None; 

    svh.AddServiceEndpoint(_serviceInterface, binding, string.Format("net.tcp://{0}:{1}", _endPoint.Address, _endPoint.Port)); 

    _stopFlag = new AutoResetEvent(false); 

    svh.Open(); 

    _stopFlag.WaitOne(); 

Y mi cliente se crea de esta manera:

var binding = new NetTcpBinding(); 

    binding.ReaderQuotas.MaxArrayLength = 2000000; 
    binding.Security.Mode = SecurityMode.None; 
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None; 
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; 
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None; 

    var scf = new ChannelFactory<IUserInputContract>(binding, "net.tcp://192.168.0.42:8001"); 
    _uiUpdateServer = scf.CreateChannel(); 

Y mi contrato (que es sólo en una biblioteca de clases que se agrega como una referencia tanto al cliente como al servidor) es:

[ServiceContract(ProtectionLevel = ProtectionLevel.None)] 
    public interface IWindowUpdateContract { 
     [OperationContract] 
     void UpdateWindowFrames(WindowFrame frame); 
     [OperationContract] 
     void WindowHasClosed(IntPtr hwnd); 
} 

I f Anhelo que la configuración de enlace y contrato que he hecho los haga idénticos y no debería tener este problema (y la seguridad debería estar desactivada). Simplemente no sé a dónde ir ahora.

Respuesta

10

Estoy de acuerdo con usted: parece que las configuraciones de seguridad para el servidor y el cliente son idénticas.

Una nota en el lado: una vez que haces:

binding.Security.Mode = SecurityMode.None; 

no creo que es necesario especificar más ajuste en el objeto "binding.Security" o por debajo de - esas líneas adicionales después de que se innecesario.

Lo que me llamó la atención es su contrato de servicios:

[ServiceContract(ProtectionLevel = ProtectionLevel.None)] 
public interface IWindowUpdateContract 
{ 
    [OperationContract] 
    void UpdateWindowFrames(WindowFrame frame); 
    [OperationContract] 
    void WindowHasClosed(IntPtr hwnd); 
} 

Estas operaciones no devuelven nada - eso es inusual. El comportamiento predeterminado para un servicio WCF es Solicitud/Respuesta: envía una solicitud y obtiene una respuesta.

O haga que devuelvan algo (un estado o algo así, como una cadena, un int), o tendrá que marcarlos como llamadas de "un solo sentido" para que WCF sepa que no puede esperar nada:

[ServiceContract(ProtectionLevel = ProtectionLevel.None)] 
public interface IWindowUpdateContract 
{ 
    [OperationContract(IsOneWay=true)] 
    void UpdateWindowFrames(WindowFrame frame); 
    [OperationContract(IsOneWay=true)] 
    void WindowHasClosed(IntPtr hwnd); 
} 

Marc

+0

he intentado añadir el atributo 'IsOneWay' y también reduje el código de enlace a la que usted ha mencionado una línea y las cosas están funcionando ahora. Muchas gracias por tu ayuda! Me resulta un poco extraño que cualquiera de esas dos cosas podría haber causado ese error específico ... ¡pero no cambié nada más y ahora funciona! – InvertedAcceleration

+0

@curiouscoder: Creo que es la configuración IsOneWay = true la que marcó la diferencia. –

Cuestiones relacionadas