Aceptar UsernameToken y BinarySecurityToken en WCF customBinding

Estoy creando un servicio web WCF con un punto final customBinding y me quedo atascado al aceptar el encabezado WS-Security que me envía otra parte. Ambos seguimos una especificación creada por el Servicio Nacional de Salud del Reino Unido, por lo que no puedo modificar los requisitos.

La estructura básica de la <wsse:Security> El encabezado debe ser el siguiente, de acuerdo con la especificación:

<wsse:Security>
    <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurityutility-1.0.xsd" wsu:Id="6CCF6A2B-11A6-11DF-86D1-236A99759561" >
        <wsu:Created>2012-06-12T09:00:00Z</wsu:Created>
        <wsu:Expires>2012-06-12T09:15:00Z</wsu:Expires>
    </wsu:Timestamp>
    <wsse:UsernameToken>
        <wsse:Username>SomeUsername</wsse:Username>
    </wsse:UsernameToken>
    <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsssoap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="30b91ede-35c2-11df-aac9-97f155153931 ">xxx...</wsse:BinarySecurityToken>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#RSA-SHA1" />
            <Reference URI="#6CCF6A2B-11A6-11DF-86D1-236A99759561" />
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>xxx...</DigestValue>
        </SignedInfo>
        <SignatureValue>xxx...</SignatureValue>
        <KeyInfo>
            <wsse:SecurityTokenReference>
                <wsse:Reference URI="#30b91ede-35c2-11df-aac9-97f155153931 "/>
            </wsse:SecurityTokenReference>
        </KeyInfo>
    </Signature>
</wsse:Security>

En mi servicio web, he intentado usar el siguiente enlace:

<customBinding>
    <binding name="wsHttpSoap11" >
        <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
        <security authenticationMode="MutualCertificate">
        </security>
        <httpTransport/>
    </binding>
</customBinding>

(La razón por la que estoy usando customBinding es que tengo que admitir ambos WS-Direccionamiento y WS-Seguridad encima JABON 1.1, y tomó el consejo de esta respuesta.)

Si ejecuto una solicitud de muestra a través de Fiddler, aparece el siguiente error en mi seguimiento de WCF:

No se puede encontrar un autenticador de token para el 'System.IdentityModel.Tokens.UserNameSecurityToken' tipo de token. No se pueden aceptar tokens de ese tipo de acuerdo con la configuración de seguridad actual.

Creo que esto se debe a que no puede autenticar el <UsernameToken>. Si cambio la seguridad vinculante a:

<security authenticationMode="UserNameForCertificate">

Entonces me sale este error:

No se puede encontrar un autenticador de token para el 'System.IdentityModel.Tokens.X509SecurityToken' tipo de token. No se pueden aceptar tokens de ese tipo de acuerdo con la configuración de seguridad actual.

Creo que esto se debe a que ahora no puede autenticar el <BinarySecurityToken>!

La pregunta, por lo tanto, es:

  1. ¿Son correctas mis suposiciones sobre la causa de los mensajes de error (que solo puede manejar un token en su configuración actual)?
  2. ¿Cómo lo configuro para aceptar ambos tokens?

Noticias

Gracias a @Yaron, ahora he agregado una extensión de enlace personalizado y tanto el Nombre de usuarioSecurityToken y Ficha de seguridad X509 están validando.

Sin embargo, ahora está fallando en la etapa en la que verifica la firma XML. La excepción devuelta en la respuesta HTTP es:

La verificación de seguridad del mensaje falló.

Si profundizo en el seguimiento de la pila en el visor de seguimiento del servicio, veo:

System.Security.Cryptography.CryptographicException...

La verificación de la firma falló.

en System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter) en System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey clave de verificación)...

¿Alguien puede ayudarme a averiguar por qué sucede esto? Estoy un poco perdido en este momento. Traté de usar algún código de muestra para intentar verificar manualmente la firma, pero dice que la firma no es válida. ¿Cómo puedo estar seguro de si lo es o no antes de volver al proveedor? ¿Es esto algo que debería funcionar? ¿Deberíamos compartir algunos certificados en algún lugar a lo largo de la línea?

preguntado el 12 de junio de 12 a las 16:06

1 Respuestas

deberá crear el enlace a partir del código.

        var b = new CustomBinding();
        var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
        sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
        sec.MessageSecurityVersion =
            MessageSecurityVersion.
                WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
        sec.IncludeTimestamp = true;
        sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;

        b.Elements.Add(sec);
        b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
        b.Elements.Add(new HttpTransportBindingElement());

(algunos de los valores son estimados ya que no puedo decir por su publicación qué versión de jabón usa o si se aplica ssl)

otro problema que puede ejecutar demasiado tarde es que necesita tener ProtectionLevel.SignOnly en sus atributos de ServiceContract, pero esto no está relacionado con esta pregunta.

Respondido el 12 de junio de 12 a las 18:06

Muchas gracias por su respuesta. Lo intentaré cuando vuelva a la oficina mañana. Mencioné en mi pregunta que estoy usando SOAP 1.1, ¿eso tiene algún efecto en su código de muestra? - Señor Crispalot

Sin embargo, si también se usa el direccionamiento, esto puede tener efecto. Si tiene algún problema, publique el jabón completo o envíemelo. Yaron Naveh

Por favor, vea mi actualización, agradecería cualquier otro consejo. Feliz de enviarle la solicitud completa si fuera útil. - Señor Crispalot

¿El seguimiento de wcf muestra alguna excepción interna? a veces está oculto debajo del principal ... si no hay más información, cree un cliente wcf para consumir este servicio, utilizando exactamente el mismo enlace de código. verifique que el cliente funcione y luego compare su jabón con el jabón real recibido. oh, espera, mirando la muestra de jabón, ¿parece que solo el cuerpo del jabón está firmado? wcf por defecto también requerirá que se firme el token de nombre de usuario y la marca de tiempo. debe haber alguna excepción interna en esto. si establece includeTimestamp en false you puede salirse con la suya con el requisito de la marca de tiempo, pero tendrá que ser - - Yaron Naveh

creativo con la marca de tiempo. Comience por encontrar esa excepción interna para que obtengamos algunos comentarios. después de encontrar el error, infórmenos también si se utiliza SSL. si es así, puede haber una manera de jugar con la configuración de CreateMutualCertificateBindingElement para convertirlo en un enlace de transporte: Yaron Naveh

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.