2012-01-27 4 views
6

Я начал изучать Apache CXF с весной. Прежде всего, я создал простую модель клиент-сервер: see hereApache CXF + Spring: простая проверка подлинности сертификата

Теперь я пытаюсь использовать простую аутентификацию сертификата. Так что я изменил конфигурационные файлы (для сервера и клиента): 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" /> 

Клиент работает отлично. Он использует его PasswordCallbackHandler. Проблема в том, что сервер, похоже, не использует свой PasswordCallbackHandler. Я запустил сервер в режиме отладки, но он не подходит для этого класса. Кто-нибудь, пожалуйста, объясните, что я делаю неправильно?

Заранее спасибо.

ПРОГРЕСС:

  1. если попытаться предоставить запрос от пользователя, который сертификат не находится в хранилище сервера, не возникает ошибка ("Нет сертификатов для пользователя WS-client1 были найдены для подписи «)

  2. из the resource:» Как вы можете увидеть в файле jbossws-cxf.xml выше, хранилище ключей пароль обработчик обратного вызова также выполнен, в то время как файл свойства имеет пароль для хранилища ключей, этот обработчик обратного вызова используется для установки пароля для каждого ключа (он должен соответствует тому, который использовался, когда каждый ключ был импортирован в хранилище). "

ответ

3

Ну, после некоторых исследований в исходном коде wss4j я понял, что в WSS4JInInterceptor нет обработчика обратного вызова в случае действия Signature (только).

0

Я полагаю, вам нужно добавить <entry key="action" value="UsernameToken Signature" /> на сервере и клиентских контекстах (в противном случае вы только подписать действие). Также может понадобиться для клиента <entry key="passwordType" value="PasswordText" /> (я не уверен, что по умолчанию: открытый текст или дайджест, я полагаю, последний).

+0

Благодарим вас за ответ. Но я хочу использовать механизм подписи. Является ли это возможным? – Dmitry

+0

Для пароля кажется, что обратный вызов все равно будет использоваться. Но это, конечно, ИМХО) – Dmitry

+0

Ваши исходные вопросы были: «Почему' PasswordCallbackHandler' не называется ». Что я вложил в свой ответ: вы пропустили соответствующее действие. Если вам нужна только подпись, вы оставите только действие «Подпись» и можете безопасно удалить записи «passwordCallbackRef» и «user» из обоих содержимого. Надеюсь, вы понимаете, что 'PasswordCallbackHandler' вызывается инфраструктурой CXF для запроса приложения, если пользователь и пароль действительны, и это не связано с подписанием. Пароль для вашего хранилища ключей должен быть определен в 'client/server.properties' соответственно. –

Смежные вопросы