我已經開始使用Spring學習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-客戶端1號證書的請求被發現)
from the resource:「正如您在上面的jbossws-cxf.xml文件中看到的,還配置了密鑰庫密碼回調處理程序;而屬性文件具有密鑰存儲區的密碼時,此回調處理程序用於爲每個鍵設置密碼(必須)匹配在商店中導入每個密鑰時使用的密鑰)「。
謝謝你的回答。但我只想使用簽名機制。可能嗎? – Dmitry 2012-01-28 19:56:33
對於密碼,似乎無論如何都必須使用回調。但這當然恕我直言) – Dmitry 2012-01-28 20:03:48
你原來的問題是「爲什麼'PasswordCallbackHandler'不叫」。我的回答是什麼:你錯過了適當的行動。如果您只需要簽名,那麼您只保留'Signature'動作,並可以安全地從兩個內容中刪除'passwordCallbackRef'和'user'條目。我希望你明白,CXF框架調用PasswordCallbackHandler來詢問應用程序,如果用戶和密碼是有效的,這與簽名無關。密鑰庫的密碼應該在'client/server.properties'中相應地定義。 – 2012-01-29 08:59:55