Я начал изучать 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. Я запустил сервер в режиме отладки, но он не подходит для этого класса. Кто-нибудь, пожалуйста, объясните, что я делаю неправильно?
Заранее спасибо.
ПРОГРЕСС:
если попытаться предоставить запрос от пользователя, который сертификат не находится в хранилище сервера, не возникает ошибка ("Нет сертификатов для пользователя WS-client1 были найдены для подписи «)
из the resource:» Как вы можете увидеть в файле jbossws-cxf.xml выше, хранилище ключей пароль обработчик обратного вызова также выполнен, в то время как файл свойства имеет пароль для хранилища ключей, этот обработчик обратного вызова используется для установки пароля для каждого ключа (он должен соответствует тому, который использовался, когда каждый ключ был импортирован в хранилище). "
Благодарим вас за ответ. Но я хочу использовать механизм подписи. Является ли это возможным? – Dmitry
Для пароля кажется, что обратный вызов все равно будет использоваться. Но это, конечно, ИМХО) – Dmitry
Ваши исходные вопросы были: «Почему' PasswordCallbackHandler' не называется ». Что я вложил в свой ответ: вы пропустили соответствующее действие. Если вам нужна только подпись, вы оставите только действие «Подпись» и можете безопасно удалить записи «passwordCallbackRef» и «user» из обоих содержимого. Надеюсь, вы понимаете, что 'PasswordCallbackHandler' вызывается инфраструктурой CXF для запроса приложения, если пользователь и пароль действительны, и это не связано с подписанием. Пароль для вашего хранилища ключей должен быть определен в 'client/server.properties' соответственно. –