*Сертификат не найден* (от клиента) при вызове веб-службы, требующей подписи

У меня возникла специфическая проблема при вызове веб-службы, которая ожидает, что сообщение будет подписано с использованием WS-Security. Если я звоню, используя свое клиентское приложение (используя Apache CXF), я получаю сообщение об ошибке HTTP 500:

*Сертификат не найден* (от клиента)

в то время как если я вызываю ту же службу, используя SoapUI, настроенную для подписи с тем же ключом и хранилищем ключей, она работает, как и ожидалось.

Я заметил, что часть <KeyInfo> вызова различается между CXF и SoapUI. С CXF (как показано ниже) KeyInfo намного более детализирован с разделами <X509Data> и т. д., в то время как вызов SoapUI содержит только простой <SecurityTokenReference>. Я подозреваю, что эта разница может быть причиной того, что сервер не может идентифицировать сертификат, используемый для подписи.

К сожалению, я не контролирую серверную часть, поэтому я не могу проводить там много исследований. Было бы неплохо узнать, известная ли это проблема и есть ли обходные пути?

С уважением, Ола

CXF:

<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="KeyId-1007572087">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-1355509614"><ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509IssuerSerial xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509IssuerName xmlns:ds="http://www.w3.org/2000/09/xmldsig#">C=SE,O=Company,CN=Company Test Corporate CA 01,SERIALNUMBER=516406-0120</ds:X509IssuerName>
    <ds:X509SerialNumber xmlns:ds="http://www.w3.org/2000/09/xmldsig#">29382</ds:X509SerialNumber>
</ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo>

Мыльный интерфейс:

<ds:KeyInfo Id="KeyId-850CCDA383426C4A1E129683271974138"><wsse:SecurityTokenReference wsu:Id="STRId-850CCDA383426C4A1E129683271974139" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:Reference URI="#CertId-850CCDA383426C4A1E129683271974137" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/></wsse:SecurityTokenReference></ds:KeyInfo>

person Ola Theander    schedule 07.02.2011    source источник


Ответы (2)


Очевидно, хитрость заключается в том, чтобы настроить свойство signalKeyIdentifier WSS4JOutInterceptor на «DirectReference», которое создает KeyInfo, подобное SoapUI, т. е. оно принимается сервером.

            <spring:bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
            <spring:constructor-arg>
                <spring:map>
                    <spring:entry key="signatureKeyIdentifier" value="DirectReference"/>
                </spring:map>
person Ola Theander    schedule 07.02.2011

Сервер ожидает, что общедоступный сертификат клиента будет встроен в запрос, что и делает значение signalKeyIdentifier DirectReference. Другой вариант заключается в том, чтобы сервер хранил все общедоступные сертификаты клиента и чтобы запрос имел идентификатор для сервера, чтобы идентифицировать правильный общедоступный сертификат и проверять подпись (ваш первый случай).

person Biju Kunjummen    schedule 07.02.2011