1

我正在尝试使用密钥库安全性,但我遇到了以下问题,不知道如何进一步进行。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

4

1 回答 1

0

因为给定的 Keystore 可能包含多个密钥,所以您需要指定要使用的密钥的名称。这是通过设置用户属性来完成的,只需将以下内容添加到您的客户端 spring:

<entry key="user" value="aliasOfKeytoUse"/>
于 2013-08-01T12:34:58.757 回答