Tengo un requisito para asegurar un punto final del servicio WCF net.tcp con WIF . Debe autenticar las llamadas entrantes en nuestro servidor de tokens. El servicio se transmite porque está diseñado para transferir grandes cantidades de datos y cosas.
Esto parece ser imposible. Y si no puedo evitar las capturas, mi Navidad se arruinará y moriré de un trago mientras los felices compradores pasan por encima de mi cuerpo que se enfría lentamente. Totalmente en serio, chicos.
¿Por qué es esto imposible? Aquí está el Catch-22.
En el cliente, necesito crear un canal con GenericXmlSecurityToken que obtengo de nuestro servidor de tokens. No hay problema.
// people around here hate the Framework Design Guidelines.
var token = Authentication.Current._Token;
var service = base.ChannelFactory.CreateChannelWithIssuedToken(token);
return service.Derp();
¿Dije "no problemo"? Problemo De hecho, el NullReferenceException
estilo de problema.
"Hermano", le pregunté al Marco, "¿ni siquiera tienes cheque nulo?" El Marco estaba en silencio, así que lo desarme y descubrí que
((IChannel)(object)tChannel).
GetProperty<ChannelParameterCollection>().
Add(federatedClientCredentialsParameter);
fue la fuente de la excepción, y que la GetProperty
llamada estaba regresando null
. Entonces, ¿WTF? Resulta que si enciendo la seguridad del Mensaje y configuro el tipo de credencial del cliente IssuedToken
, esta propiedad ahora existe en ClientFactory
(protip: No hay un equivalente de "SetProperty" en IChannel, el bastardo).
<binding name="OMGWTFLOL22" transferMode="Streamed" >
<security mode="Message">
<message clientCredentialType="IssuedToken"/>
</security>
</binding>
Dulce. No más NRE. Sin embargo, ahora mi cliente tiene una falla al nacer (todavía lo amo, aunque). Excavando los diagnósticos de WCF (resumen: haz que tus peores enemigos hagan esto después de aplastarlos y conducirlos ante ti, pero justo antes de disfrutar de las lamentaciones de sus mujeres y niños), veo que es debido a una falta de coincidencia de seguridad entre el servidor y el cliente.
La actualización solicitada no es compatible con 'net.tcp: // localhost: 49627 / MyService'. Esto podría deberse a enlaces no coincidentes (por ejemplo, seguridad habilitada en el cliente y no en el servidor).
Verificando los diags del host (de nuevo: aplastar, conducir, leer registros, disfrutar lamentaciones), veo que esto es cierto
El tipo de protocolo application / ssl-tls se envió a un servicio que no admite ese tipo de actualización.
"Bueno, yo mismo", le digo, "¡Solo activaré la seguridad de mensajes en el host!" Y yo si. Si desea saber cómo se ve, es una copia exacta de la configuración del cliente. Buscar.
Resultado: Kaboom.
El enlace ('NetTcpBinding', ' http://tempuri.org/ ') admite la transmisión que no se puede configurar junto con la seguridad a nivel de mensaje. Considere elegir un modo de transferencia diferente o elegir el nivel de seguridad de transporte.
Por lo tanto, mi host no se puede transmitir y proteger a través de tokens . 22 capturas.
tl; dr: ¿Cómo puedo asegurar un punto final net.tcp WCF transmitido mediante WIF?
<security mode="Transport" /> <transport clientCredentialType="IssuedToken" /> </security>
TransportWithMessageCredential
El modo puede ser otra opción.Respuestas:
WCF tiene problemas en algunas áreas con la transmisión (lo estoy mirando, MTOM 1 ) debido a un problema fundamental en la forma en que no realiza la autenticación previa de la manera en que la mayoría de la gente pensaría que debería funcionar (solo afecta las solicitudes posteriores para ese canal , no es la primera solicitud) Ok, entonces este no es exactamente tu problema, pero síguelo ya que llegaré al tuyo al final. Normalmente, el desafío HTTP funciona así:
Ahora, si alguna vez intenta habilitar la transmisión MTOM en un punto final WCF en el servidor, no se quejará. Pero, cuando lo configura en el proxy del cliente (como debe hacerlo, deben coincidir con los enlaces) explotará en una muerte ardiente. La razón de esto es que la secuencia de eventos anterior que WCF está tratando de prevenir es la siguiente:
Tenga en cuenta que acaba de enviar 200 MB al servidor cuando solo necesitaba enviar 100 MB. Bueno, este es el problema. La respuesta es enviar la autenticación en el primer intento, pero esto no es posible en WCF sin escribir un comportamiento personalizado. De todos modos, estoy divagando.
Tu problema
Primero, déjame decirte que lo que estás intentando es imposible 2 . Ahora, para que dejes de girar tus ruedas, déjame decirte por qué:
Me parece que ahora estás vagando en una clase de problema similar. Si habilita la seguridad a nivel de mensaje, el cliente debe cargar todo el flujo de datos en la memoria antes de que pueda cerrar el mensaje con la función hash habitual y la firma xml requerida por ws-security. Si tiene que leer la transmisión completa para firmar el mensaje único (que no es realmente un mensaje, pero es una transmisión continua única), puede ver el problema aquí. WCF tendrá que transmitirlo una vez "localmente" para calcular la seguridad del mensaje, luego transmitirlo nuevamente para enviarlo al servidor. Esto es claramente una tontería, por lo que WCF no permite la seguridad a nivel de mensaje para la transmisión de datos.
Entonces, la respuesta simple aquí es que debe enviar el token como un parámetro al servicio web inicial o como un encabezado SOAP y usar un comportamiento personalizado para validarlo. No puede usar WS-Security para hacer esto. Francamente, esto no es solo un problema de WCF: no puedo ver cómo podría funcionar prácticamente para cualquier otra pila.
Resolviendo el problema MTOM
Esto es solo un ejemplo de cómo resolví mi problema de transmisión de MTOM para la autenticación básica, por lo que tal vez podría tomar las agallas de esto e implementar algo similar para su problema. El quid de la cuestión es que para habilitar su inspector de mensajes personalizado, debe deshabilitar toda noción de seguridad en el proxy del cliente (permanece habilitado en el servidor), aparte del nivel de transporte (SSL):
Tenga en cuenta que he desactivado la seguridad del transporte aquí porque lo proporcionaré yo mismo utilizando un inspector de mensajes y un comportamiento personalizado:
Por lo tanto, este ejemplo es para cualquier persona que esté sufriendo el problema MTOM, pero también como un esqueleto para que implemente algo similar para autenticar su token generado por el servicio de token protegido por WIF primario.
Espero que esto ayude.
(1) Grandes datos y transmisión
(2) Seguridad de mensajes en WCF (ver "desventajas")
fuente
MTOM and Basic Authorization
y MTOM y OAuth2 ?