Как правильно добавить шифрование / дешифрование в spring-ws (wss4j)? - PullRequest
6 голосов
/ 15 июля 2011

Я развернул 2 веб-приложения, одно из которых представляет веб-сервис, а другое представляет клиент.При использовании SIGNING и TIMESTAMP-ing все работает нормально, клиент печатает сообщение (но я думаю, что он не переопределяет ttl по умолчанию 300 с), подписывает сообщение своим сертификатом x509 и отправляет его в ws.С другой стороны, он получает сообщение и может проверить временную метку и сертификат / подпись на доверенном сертификате клиентов в своем хранилище ключей.

Проблема возникает, когда я добавляю операцию шифрования в свою конфигурацию.Кажется, что клиент может зашифровать сообщение, но ws, похоже, не заинтересован в расшифровке сообщения.Он просто видит, что не существует сопоставления конечных точек для

[SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#}EncryptedData] 

и выбрасывает

WebServiceTransportException: Not Found [404] exception.

ТАК, кто-то может объяснить, что мне нужно сделать, чтобы добиться отметки времени, подписи с x509 и шифрованияопять же с x509?

частью серверного приложения-контекста:

<bean id="wss4jSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor"> 
        <!-- valiadation -->
        <property name="validationActions" value="Timestamp Signature Encrypt"/> 
        <property name="enableSignatureConfirmation" value="true"/> 
        <property name="validationSignatureCrypto"> 
            <ref bean="keystore"/> 
        </property> 
        <property name="validationDecryptionCrypto"> 
                <ref bean="keystore"/> 
        </property> 
        <property name="validationCallbackHandler"> 
            <bean class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler"> 
                <property name="privateKeyPassword" value="password"/> 
            </bean> 
        </property> 
         <!-- timestamp options -->
        <property name="timestampStrict" value="true"/> 
        <property name="timeToLive" value="30"/> 
        <property name="timestampPrecisionInMilliseconds" value="true"/> 
         <!-- signing and encryption -->
        <property name="securementActions" value="Timestamp Signature Encrypt"/> 
        <property name="securementUsername" value="wsserver"/> 
        <property name="securementPassword" value="password"/> 
        <property name="securementSignatureKeyIdentifier" value="DirectReference"/> 

        <property name="securementSignatureCrypto"> 
            <ref bean="keystore"/> 
        </property> 
        <property name="securementEncryptionUser" value="wsclient"/> 
        <property name="securementEncryptionCrypto"> 
            <ref bean="keystore"/> 
        </property>
</bean>
 <!-- keystore -->
<bean id="keystore" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean"> 
          <property name="keyStorePassword" value="password"/> 
          <property name="keyStoreLocation" value="WEB-INF/MyTruststore.jks"/> 
</bean>
<!-- interceptors -->
<sws:interceptors> 
<ref bean="wss4jSecurityInterceptor"/> 
<bean id="validatingInterceptor" 
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"> 
  <property name="schema" value="/WEB-INF/person.xsd"/>
  <property name="validateRequest" value="true"/> 
  <property name="validateResponse" value="true"/> 
</bean> 
    <bean id ="loggingInterceptor"    class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"> 
    </bean> 
    </sws:interceptors>

Клиент в основном использует ту же конфигурацию, за исключением того, что он использует открытый ключ сервера для шифрования и свой закрытый ключ для дешифрования.

С хранилищами все в порядке, наверное, потому что подпись работает нормально ... Когда я добавляю действие Encrypt, все просто разваливается, часть журнала сервера говорит:

DEBUG [org.springframework.ws.server.MessageTracing.recei ved] - Received request [SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#}EncryptedData]
DEBUG [org.springframework.ws.server.endpoint.mapping.Pay loadRootAnnotationMethodEndpointMapping] - Looking up endpoint for [{http://www.w3.org/2001/04/xmlenc#}EncryptedData]
DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Endpoint mapping [org.springframework.ws.server.endpoint.mapping.Pay loadRootAnnotationMethodEndpointMapping@30a14083] has no mapping for request
...
No endpoint mapping found for [SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#}EncryptedData]
org.springframework.ws.client.WebServiceTransportE xception: Not Found [404]
...

Я думаю, что долженкак-то проинструктировать ws дешифровать тело SOAP, прежде чем оно начнет искать конечную точку для сообщения, но я не знаю как.Предложения?

Ответы [ 2 ]

6 голосов
/ 13 февраля 2013

Поскольку ваши комментарии были полезны, но отчасти неполны, я попытался ответить немного подробнее:

В весеннем уроке метод конечной точки аннотируется с помощью @PayloadRoot: @PayloadRoot(localPart = "orderInput", namespace = "http://samples")

Это прекрасно работает, когда мыльное сообщение не зашифровано.PayloadRootAnnotationMethodEndpointMapping может отображать сообщение мыла в соответствующий метод.

Когда сообщение мыла зашифровано, PayloadRootAnnotationMethodEndpointMapping не может отобразить сообщение мыла, поскольку у перехватчика безопасности еще не было времени для его расшифровки.Решение состоит в том, чтобы заменить @PayloadRoot на @SoapAction.

Когда получено мыльное сообщение, spring-ws сначала вызывает PayloadRootAnnotationMethodEndpointMapping, а затем SoapActionAnnotationMethodEndpointMapping.Вы можете использовать оба, чтобы быть полностью совместимыми с непружинным клиентом (например, ось или .net):

@PayloadRoot(localPart = "orderInput", namespace = "http://samples")
@SoapAction("http://samples/order") 

Последнее, но не менее важное: если вы используете весенний клиент с защищенным сообщением мыла,весна не отправляет действие мыла автоматически.Ваш сервер не сможет сопоставить мыльное сообщение с соответствующим действием.Чтобы решить эту проблему, вы должны использовать WebServiceMessageCallback:

ClientMessageCallBack callBack = new ClientMessageCallBack(
"http://samples/order");                    
Object output = wsTemplate.marshalSendAndReceive(inputObject, callBack);

, где класс ClientMessageCallBack равен

public final class ClientMessageCallBack 
    implements WebServiceMessageCallback {

    /**the soapAction to be appended to the soap message.*/
    private String soapAction;

    /**constructor.
     * @param action the soapAction to be set.*/
    public ClientMessageCallBack(final String action) {
        this.soapAction = action;
    }

    @Override
    public void doWithMessage(final WebServiceMessage message) 
            throws IOException, TransformerException {

        if (message instanceof SoapMessage) {
            SoapMessage soapMessage = (SoapMessage) message;
            soapMessage.setSoapAction(soapAction);
        }

    }
}
0 голосов
/ 15 августа 2015

это происходит потому, что вы не определили свойство securementEncryptionParts.Это вызывает шифрование всего тела и делает эту ошибку

...