2011-07-15 31 views
6

Implementé 2 aplicaciones web, una que representa el servicio web y otra que representa al cliente ws. Cuando se utiliza la firma y TIMESTAMP-ción, todo funciona, mensaje de sellos cliente fino (pero creo que no anula el TTL por defecto 300s), firma el mensaje con su certificado X509, y lo envía a WS. Él, por otro lado, recibe un mensaje y puede validar la marca de tiempo y el certificado/firma contra el certificado de confianza de los clientes en su almacén de claves.¿Cuál es la forma correcta de agregar cifrado/descifrado en spring-ws (wss4j)?

problema surge cuando agrego operación Cifrar a mi configuración. El cliente parece ser capaz de encriptar el mensaje, pero parece que no le interesa el descifrado del mensaje. Él sólo ve que no hay ninguna asignación punto final para

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

y lanza

 
WebServiceTransportException: Not Found [404] exception. 

PS puede alguien explicar lo que tengo que hacer con el fin de lograr sellado de tiempo, la firma con x509 y cifrado, de nuevo con x509 ?

parte del servidor de aplicaciones contexto:

<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> 

básicamente cliente utiliza la misma configuración, excepto que utiliza la clave pública del servidor para el cifrado, y su clave privada para el descifrado.

Keystores están bien, supongo, ya que la firma trabaja muy bien ... Todo juust se desmorona cuando agrego acción Cifrar, parte del registro del servidor dice:

 
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 [email protected]] 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] 
... 

Creo que debe instruir alguna manera ws para descifrar SOAP body antes de que comience a buscar un punto final para el mensaje, pero no sé cómo. Sugerencias?

+1

He resuelto el problema, bueno, un poco. El caso es que utilicé la anotación @PayloadRoot, pero mi carga útil nunca fue algo que mi aplicación pudiera asignar a un punto final ... simplemente era EncryptedData. Cuando cambié Ann a @ SoapAction y agregué la interfaz WebServiceMessageCallback() a marshalSendAndReceive() del cliente, el servicio web supuso que no tenía correspondencia para la carga útil EncryptedData, por lo que buscó la asignación con SoapActionAnnotationMethodEndpointMapping y encontró una. Que, y solo que, cuando el servidor encontró la asignación para la solicitud, descifró el cuerpo de SOAP ... y descubrió que PayloadRoot estaba allí :) – mare

+0

¡Por favor, cierre la pregunta! –

+0

En el contexto de la aplicación del servidor, ¿dónde especifica el alias clave para el descifrado y la firma? – WarLord

Respuesta

6

Desde sus comentarios eran útiles pero un poco incompleta, me tomó una sesión de responder con un poco más de un detalle.

En el tutorial de la primavera, el método de punto final se anota con @PayloadRoot: @PayloadRoot(localPart = "orderInput", namespace = "http://samples")

Esto funciona bien cuando el mensaje de jabón no está encriptada. PayloadRootAnnotationMethodEndpointMapping puede mapear al mensaje de jabón al método correspondiente.

Cuando el mensaje de jabón está encriptado, PayloadRootAnnotationMethodEndpointMapping no puede asignar el mensaje de error porque el interceptor de seguridad aún no tiene tiempo para descifrarlo. La solución es reemplazar @PayloadRoot con @SoapAction.

Cuando se recibe un mensaje de soap, spring-ws llama primero a PayloadRootAnnotationMethodEndpointMapping y luego a SoapActionAnnotationMethodEndpointMapping. Se puede utilizar tanto con el fin de ser completamente compatible con el cliente no la primavera (por ejemplo, eje o .net):

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

Por último, pero no menos importante: Si está utilizando un cliente de primavera con el mensaje de jabón garantizado, que la primavera hace no envíe la acción de jabón automáticamente. Su servidor no podrá asignar el mensaje de jabón con la acción adecuada.Para resolver este problema, se debe utilizar un WebServiceMessageCallback:

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

donde la clase ClientMessageCallBack es

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

¡mucho! en lugar de su ClientMessageCallBack, utilicé .marshalSendAndReceive (solicitud, nueva SoapActionCallback ("http://spring.io/guides/gs-producing-web-service")); – Janiiik

0

esto sucede porque no se ha definido la propiedad securementEncryptionParts. Causa encriptar todo el cuerpo y hacer a este Error

Cuestiones relacionadas