我应该应用什么WS-Security设置来连接到wsdl描述的SOAP服务?

时间:2014-09-11 08:54:37

标签: java wsdl cxf webservice-client ws-security

我被赋予了为特定Web服务创建java客户端的任务,该服务由以下wsdl文件描述:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Person" targetNamespace="http://tempuri.org/">
  <wsp:Policy wsu:Id="WSHttpBinding_IPersonService_policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:TransportToken>
              <wsp:Policy>
                <sp:HttpsToken RequireClientCertificate="false" />
              </wsp:Policy>
            </sp:TransportToken>
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic256 />
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <sp:Layout>
              <wsp:Policy>
                <sp:Strict />
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp />
          </wsp:Policy>
        </sp:TransportBinding>
        <sp:EndorsingSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
              <wsp:Policy>
                <sp:BootstrapPolicy>
                  <wsp:Policy>
                    <sp:SignedParts>
                      <sp:Body />
                      <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
                      <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
                      <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
                      <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
                      <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
                      <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
                      <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
                    </sp:SignedParts>
                    <sp:EncryptedParts>
                      <sp:Body />
                    </sp:EncryptedParts>
                    <sp:TransportBinding>
                      <wsp:Policy>
                        <sp:TransportToken>
                          <wsp:Policy>
                            <sp:HttpsToken RequireClientCertificate="false" />
                          </wsp:Policy>
                        </sp:TransportToken>
                        <sp:AlgorithmSuite>
                          <wsp:Policy>
                            <sp:Basic256 />
                          </wsp:Policy>
                        </sp:AlgorithmSuite>
                        <sp:Layout>
                          <wsp:Policy>
                            <sp:Strict />
                          </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp />
                      </wsp:Policy>
                    </sp:TransportBinding>
                    <sp:SignedSupportingTokens>
                      <wsp:Policy>
                        <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                          <wsp:Policy>
                            <sp:WssUsernameToken10 />
                          </wsp:Policy>
                        </sp:UsernameToken>
                      </wsp:Policy>
                    </sp:SignedSupportingTokens>
                    <sp:Wss11>
                      <wsp:Policy />
                    </sp:Wss11>
                    <sp:Trust10>
                      <wsp:Policy>
                        <sp:MustSupportIssuedTokens />
                        <sp:RequireClientEntropy />
                        <sp:RequireServerEntropy />
                      </wsp:Policy>
                    </sp:Trust10>
                  </wsp:Policy>
                </sp:BootstrapPolicy>
              </wsp:Policy>
            </sp:SecureConversationToken>
          </wsp:Policy>
        </sp:EndorsingSupportingTokens>
        <sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy />
        </sp:Wss11>
        <sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:MustSupportIssuedTokens />
            <sp:RequireClientEntropy />
            <sp:RequireServerEntropy />
          </wsp:Policy>
        </sp:Trust10>
        <wsaw:UsingAddressing />
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
  <wsdl:types>
    <xsd:schema targetNamespace="http://tempuri.org/Imports">
      <xsd:import schemaLocation="https://localhost:442/Services/Person.svc?xsd=xsd0" namespace="http://tempuri.org/" />
      <xsd:import schemaLocation="https://localhost:442/Services/Person.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="IPersonService_GetSomething_InputMessage">
    <wsdl:part name="parameters" element="tns:GetSomething" />
  </wsdl:message>
  <wsdl:message name="IPersonService_GetSomething_OutputMessage">
    <wsdl:part name="parameters" element="tns:GetSomethingResponse" />
  </wsdl:message>
  <wsdl:portType name="IPersonService">
    <wsdl:operation name="GetSomething">
      <wsdl:input wsaw:Action="http://tempuri.org/IPersonService/GetSomething" message="tns:IPersonService_GetSomething_InputMessage" />
      <wsdl:output wsaw:Action="http://tempuri.org/IPersonService/GetSomethingResponse" message="tns:IPersonService_GetSomething_OutputMessage" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="WSHttpBinding_IPersonService" type="tns:IPersonService">
    <wsp:PolicyReference URI="#WSHttpBinding_IPersonService_policy" />
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetSomething">
      <soap12:operation soapAction="http://tempuri.org/IPersonService/GetSomething" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="Person">
    <wsdl:port name="WSHttpBinding_IPersonService" binding="tns:WSHttpBinding_IPersonService">
      <soap12:address location="https://localhost:442/Services/Person.svc" />
      <wsa10:EndpointReference>
        <wsa10:Address>https://localhost:442/Services/Person.svc</wsa10:Address>
      </wsa10:EndpointReference>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

我使用Apache CXF的wsdl2java创建了Java客户端,并在使用new AddressingFeature(true)的客户端调用中创建了Java客户端,因为服务使用HTTPS,如下所示:

Person p = new Person();
IPersonService iPersonService = p.getWSHttpBindingIPersonService(new AddressingFeature(true));
System.out.println(iPersonService.getSomething());

但我得到以下例外:

  

org.apache.cxf.binding.soap.SoapFault:无法处理邮件。这很可能是因为操作“http://tempuri.org/IPersonService/GetSomething”不正确,或者因为邮件包含无效或过期的安全上下文令牌,或者因为绑定之间存在不匹配。如果服务因不活动而中止通道,则安全上下文令牌将无效。要防止服务中止空闲会话,请过早增加服务端点绑定的接收超时。

到目前为止,我已尝试添加ws-security.usernamews-security.password,但它不起作用,我得到了同样的例外:

((BindingProvider) iPersonService).getRequestContext() 
   .put("ws-security.username", "user"); 
((BindingProvider) iPersonService).getRequestContext() 
   .put("ws-security.password", "password"); 

所以,很可能我没有应用某种安全设置。任何人都可以描述我应该为这个特定的wsdl申请哪些WS-Security设置?

更新:
添加了xsd架构:https://gist.github.com/the-lay/12c2dc5091c5dc783f00

3 个答案:

答案 0 :(得分:3)

答案 1 :(得分:3)

问题如下:

  • 我没有意识到,如果我不使用cxf-rt-ws-policy依赖关系,那么WSDL的策略设置将被默默忽略。要解决此问题,我已将此添加到我的pom.xml(或者您可以添加整个捆绑包 - cxf-bundle包)并从那里开始我还有另一个例外,但那是无论如何都要取得进步。

  • 在此之后,即使我在我的cxf.xml中拥有了#34;也没有提供用户名&#34;问题是我使用了错误的jaxws:client名称属性。我已经使用了服务名称,但您必须使用端口名称(可以在wsdl文件的末尾找到),并且还必须为该客户端使用createdFromAPI属性。所以,最后看起来应该是这样的:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"
       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/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

    <cxf:bus> <!-- it's not mandatory, just easier with this -->
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus>

    <jaxws:client name="{http://tempuri.org/}WSHttpBinding_IPersonService"
                  createdFromAPI="true">
        <jaxws:properties>
            <entry key="ws-security.username" value="Username"/>
            <entry key="ws-security.password" value="Password"/>
        </jaxws:properties>
    </jaxws:client>
</beans>

答案 2 :(得分:1)

我使用Glassfish Metro和Netbeans来使用类似的服务。这里有一个很好的指南: https://metro.java.net/1.5/guide/Creating_a_Client_to_Consume_a_WSIT_Enabled_Web_Service.html

创建Web服务客户端后,您可以在Web Service References文件夹中看到它,右键单击它并选择&#34;编辑Web服务属性...&#34;。在弹出窗口中,您可以输入登录详细信息。

在servlet中,您可以使用您编写的代码来访问Person。