我正在尝试使用密钥库安全性,但我遇到了以下问题,不知道如何进一步进行。org.apache.cxf.binding.soap.SoapFault:指定操作的空用户名。这是我的设置。
我的证书由以下命令生成
keytool -genkeypair -alias aka -keypass myAliasPassword -keystore privatestore.jks -storepass keyStorePassword -dname "CN=aka" -keyalg RSA
keytool -selfcert -alias aka -keystore privatestore.jks -storepass keyStorePassword -keypass myAliasPassword
keytool -export -alias aka -file key.rsa -keystore privatestore.jks -storepass keyStorePassword
keytool -import -alias aka -file key.rsa -keystore publicstore.jks -storepass keyStorePassword
他们看起来像这样
C:\test\employee-usertoken>keytool -list -v -keystore privatestore.jks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: myalias
Creation date: Apr 29, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=myCN
Issuer: CN=myCN
Serial number: 517e8a5e
Valid from: Mon Apr 29 10:57:34 EDT 2013 until: Sun Jul 28 10:57:34 EDT 2013
Certificate fingerprints:
MD5: AE:D8:7E:89:33:55:82:41:30:88:6D:D3:F7:7E:CA:AD
SHA1: 02:A5:11:E7:D1:EB:61:0E:39:2C:8D:50:EF:EB:46:88:DF:86:34:94
Signature algorithm name: SHA1withRSA
Version: 3
*******************************************
*******************************************
C:\test\employee-usertoken>keytool -list -v -keystore publicstore.jks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: myalias
Creation date: Apr 29, 2013
Entry type: trustedCertEntry
Owner: CN=myCN
Issuer: CN=myCN
Serial number: 517e8a5e
Valid from: Mon Apr 29 10:57:34 EDT 2013 until: Sun Jul 28 10:57:34 EDT 2013
Certificate fingerprints:
MD5: AE:D8:7E:89:33:55:82:41:30:88:6D:D3:F7:7E:CA:AD
SHA1: 02:A5:11:E7:D1:EB:61:0E:39:2C:8D:50:EF:EB:46:88:DF:86:34:94
Signature algorithm name: SHA1withRSA
Version: 3
*******************************************
*******************************************
C:\test\employee-usertoken>
我的客户端 Spring 配置如下
<?xml version="1.0" encoding="UTF-8"?>
<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">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="clientKeystoreTokenCallback" class="com.jpmorgan.ibanker.client.ClientKeyStoreTokenCallback" />
<jaxws:client id="empGreetClient"
serviceClass="com.jpmorgan.ibanker.EmployeeGreet"
address="http://localhost:100/employee-usertoken/webservices/EmpGreet" >
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature"/>
<entry key="signaturePropFile" value="client_sign.properties"/>
<entry key="passwordCallbackRef">
<ref bean="clientKeystoreTokenCallback"/>
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
</beans>
我的服务器端弹簧配置如下
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="keyStoreTokenCallback" class="com.jpmorgan.ibanker.ServerKeyStoreTokenCallback" />
<jaxws:endpoint
id="empGreetSecure"
implementor="com.jpmorgan.ibanker.EmployeeGreetImpl"
address="/EmpGreet" >
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature"/>
<entry key="signaturePropFile" value="server_sign.properties"/>
<entry key="passwordCallbackRef">
<ref bean="keyStoreTokenCallback"/>
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
</beans>
client_sign 属性文件如下
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.keystore.alias=aka
org.apache.ws.security.crypto.merlin.keystore.file=publicstore.jks
server_sign 属性如下
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.keystore.alias=aka
org.apache.ws.security.crypto.merlin.keystore.file=privatestore.jks
堆栈跟踪如下
2013-04-29 15:04:06,827 [Main Thread] INFO org.apache.cxf.service.factory.ReflectionServiceFactoryBean - Creating Service {http://ibanker.jpmorgan.com/}EmployeeGreetService from class com.jpmorgan.ibanker.EmployeeGreet
2013-04-29 15:04:07,748 [Main Thread] WARN org.apache.cxf.phase.PhaseInterceptorChain - Interceptor for {http://ibanker.jpmorgan.com/}EmployeeGreetService#{http://ibanker.jpmorgan.com/}getEmployee has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: Empty username for specified action.
at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:226)
at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:136)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
at $Proxy36.getEmployee(Unknown Source)
at com.jpmorgan.ibanker.client.EmpGreetClient.main(EmpGreetClient.java:20)
Exception in thread "Main Thread" javax.xml.ws.soap.SOAPFaultException: Empty username for specified action.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
at $Proxy36.getEmployee(Unknown Source)
at com.jpmorgan.ibanker.client.EmpGreetClient.main(EmpGreetClient.java:20)
Caused by: org.apache.cxf.binding.soap.SoapFault: Empty username for specified action.
at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:226)
at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:136)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
... 2 more
我已经用谷歌搜索了等,但没有运气。邮件列表上的几个类似问题没有得到解答。如果有人可以帮助我解决这个问题,我将不胜感激。
我正在使用 java 1.6 和 cxf 2.7.x