2012-01-27 15 views
6

Comencé a aprender Apache CXF con Spring. En primer lugar, he creado un modelo simple de cliente/servidor: see hereApache CXF + Spring: Autenticación de certificado simple

Ahora estoy tratando de usar una autenticación de certificado simple. Así que he cambiado los archivos de configuración (para el servidor y el cliente): cxf-servlet.xml:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:jaxws="http://cxf.apache.org/jaxws" 
xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> 

<jaxws:endpoint 
    id="helloWorld" 
    implementor="service.HelloWorldImpl" 
    address="/HelloWorld"> 

    <jaxws:features> 
     <bean class="org.apache.cxf.feature.LoggingFeature"/> 
    </jaxws:features> 
    <jaxws:inInterceptors> 
     <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/> 
     <ref bean="WSS4JInInterceptor"/> 
    </jaxws:inInterceptors> 
</jaxws:endpoint> 

<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> 
    <constructor-arg> 
     <map> 
      <entry key="action" value="Signature"/> 
      <entry key="passwordCallbackRef"> 
       <ref bean="passwordCallback"/> 
      </entry> 
      <entry key="signaturePropFile" value="server_sign.properties"/> 
     </map> 
    </constructor-arg> 
</bean> 
<bean id="passwordCallback" class="service.PasswordCallbackHandler" /> 

server_sign.properties:

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin 
org.apache.ws.security.crypto.merlin.keystore.type=jks 
org.apache.ws.security.crypto.merlin.keystore.password=keyStorePassword 
org.apache.ws.security.crypto.merlin.file=publicstore.jks 

cxf-client-servlet.xml:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:jaxws="http://cxf.apache.org/jaxws" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
    http://cxf.apache.org/jaxws 
    http://cxf.apache.org/schema/jaxws.xsd"> 

<bean id="client" class="service.HelloWorld" factory-bean="clientFactory" factory-method="create"/> 

<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> 
    <property name="serviceClass" value="service.HelloWorld"/> 
    <property name="address" value="http://localhost:8080/services/HelloWorld"/> 
    <property name="outInterceptors"> 
     <list> 
      <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/> 
      <ref bean="WSS4JOutInterceptor"/> 
     </list> 
    </property> 
</bean> 

<bean id="WSS4JOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> 
    <property name="properties"> 
     <map> 
      <entry key="action" value="Signature"/> 
      <entry key="user" value="ws-client" /> 
      <entry key="passwordCallbackRef"> 
       <ref bean="passwordCallback"/> 
      </entry> 
      <entry key="signaturePropFile" value="client_sign.properties"/> 
     </map> 
    </property> 
</bean> 

<bean id="passwordCallback" class="client.PasswordCallbackHandler" /> 

El cliente funciona a la perfección. Utiliza su PasswordCallbackHandler. El problema es que el servidor no parece usar PasswordCallbackHandler. He ejecutado el servidor en un modo de depuración, pero no va a esta clase. ¿Puede alguien, por favor, explicar, qué hago mal?

Gracias de antemano.

PROGRESO:

  1. si se intenta proporcionar una petición de un usuario, que el certificado no está en almacén de claves del servidor, se produce el error ("No hay certificados de usuario WS-cliente1 fueron encontrados a la firma ")

  2. de the resource:" Como se puede ver en el archivo jbossws-cxf.xml anteriormente, un manejador de devolución de llamada contraseña del almacén está también configurado, mientras que el archivo de propiedades tiene la contraseña del almacén de claves, este controlador de devolución de llamada se usa para establecer la contraseña de cada tecla (tiene que coincide con el utilizado cuando se importó cada clave en la tienda). "

Respuesta

3

Bueno, después de algunas investigaciones en el código fuente de wss4j me he dado cuenta de que no hay un controlador de devolución de llamada en el WSS4JInInterceptor en el caso de la acción Signature (solo).

0

supongo que es necesario agregar <entry key="action" value="UsernameToken Signature" /> a ambos contextos de servidor y cliente (de lo contrario sólo haya firmar acción). También para el cliente <entry key="passwordType" value="PasswordText" /> podría ser necesario (no estoy seguro de lo que es predeterminado: texto sin formato o resumen, supongo que el último).

+0

Gracias por su respuesta. Pero solo quiero utilizar el mecanismo de firma. ¿Es posible? – Dmitry

+0

Para la contraseña, parece que la devolución de llamada debe estar en uso. Pero eso es por supuesto en mi humilde opinión) – Dmitry

+0

Sus preguntas originales eran "¿Por qué' PasswordCallbackHandler' no se llama ". ¿Qué es lo que he puesto en mi respuesta? Te has perdido la acción adecuada. Si solo necesita la firma, solo deja la acción 'Firma' y puede eliminar de forma segura las entradas' passwordCallbackRef' y 'user' de ambos contenidos. Espero que entienda que el marco CXF llama a 'PasswordCallbackHandler' para preguntarle a la aplicación, si el usuario y la contraseña son válidos, y eso no tiene nada que ver con la firma. La contraseña para su keystore debe definirse en 'client/server.properties' correspondientemente. –

Cuestiones relacionadas