2016-06-21 8 views
1

Могло бы действительно помочь с этим, так как я уже несколько дней ударяю головой о кирпичную стену.Исключение политики Apache CXF (безопасность WS). Конфигурация безопасности не удалось обнаружить.

Я реализовал очень простую службу JAX-WS с использованием Apache CXF, я пытаюсь добавить WS-SecurityPolicies зашифровать и подписать тело сообщения, однако на стороне клиента я получаю следующее исключение:

org.apache.cxf.ws.policy.PolicyException: Security configuration could not be detected. Potential cause: Make sure jaxws:client element with name attribute value matching endpoint port is defined as well as a security.signature.properties element within it. 
    at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractCommonBindingHandler.unassertPolicy(AbstractCommonBindingHandler.java:92) 
    at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getSignatureBuilder(AbstractBindingBuilder.java:1797) 
    at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignature(AsymmetricBindingHandler.java:693) 
    at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:171) 
    at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.handleBinding(AsymmetricBindingHandler.java:110) 
    at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessageInternal(PolicyBasedWSS4JOutInterceptor.java:190) 
    at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:109) 
    at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:96) 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) 
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277) 
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139) 

Это мой applicationContext.xml стороне клиента:

<bean id="passwordCallback" 
     class="com.example.payment.engine.soap.service.ClientPasswordCallback"></bean> 

<jaxws:client 
    name="{http://service.soap.engine.payment.example.com/}HelloWorldImplService" 
    createdFromAPI="true" id="helloClient" 
    serviceClass="com.example.payment.engine.soap.service.HelloWorld" 
    address="http://localhost:8080/payment-engine/api/soap/hello"> 
    <jaxws:properties> 
     <entry key="ws-security.callback-handler" value-ref="passwordCallback" /> 
     <entry key="ws-security.encryption.properties" value="crypto.properties" /> 
     <entry key="ws-security.signature.properties" value="crypto.properties" /> 
     <entry key="ws-security.encryption.username" value="server" /> 
    </jaxws:properties> 
</jaxws:client> 

Это клиент crypto.properties

org.apache.ws.security.crypto.merlin.keystore.file=client-keystore.jks 
org.apache.ws.security.crypto.merlin.keystore.password=client-pass 
org.apache.ws.security.crypto.merlin.keystore.private.password=key-pass 
org.apache.ws.security.crypto.merlin.keystore.alias=client 

И, наконец, это WSDL:

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:tns="http://service.soap.engine.payment.example.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy" 
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" name="HelloWorldImplService" 
    targetNamespace="http://service.soap.engine.payment.example.com/"> 
    <wsdl:types> 
     <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.soap.engine.payment.example.com/" 
      elementFormDefault="unqualified" targetNamespace="http://service.soap.engine.payment.example.com/" version="1.0"> 
      <xs:element name="sayHello" type="tns:sayHello" /> 
      <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" /> 
      <xs:complexType name="sayHello"> 
       <xs:sequence /> 
      </xs:complexType> 
      <xs:complexType name="sayHelloResponse"> 
       <xs:sequence> 
        <xs:element minOccurs="0" name="return" type="xs:string" /> 
       </xs:sequence> 
      </xs:complexType> 
     </xs:schema> 
    </wsdl:types> 
    <wsdl:message name="sayHelloResponse"> 
     <wsdl:part element="tns:sayHelloResponse" name="parameters"></wsdl:part> 
    </wsdl:message> 
    <wsdl:message name="sayHello"> 
     <wsdl:part element="tns:sayHello" name="parameters"></wsdl:part> 
    </wsdl:message> 
    <wsdl:portType name="HelloWorld"> 
     <wsdl:operation name="sayHello"> 
      <wsdl:input message="tns:sayHello" name="sayHello"></wsdl:input> 
      <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse"></wsdl:output> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="HelloWorldImplServiceSoapBinding" type="tns:HelloWorld"> 
    <wsp:PolicyReference URI="#HelloWorldBindingPolicy"/> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
     <wsdl:operation name="sayHello"> 
      <soap:operation soapAction="" style="document" /> 
      <wsdl:input name="sayHello"> 
       <wsp:PolicyReference URI="#HelloWorldInputBindingPolicy" /> 
       <soap:body use="literal" /> 
      </wsdl:input> 
      <wsdl:output name="sayHelloResponse"> 
       <wsp:PolicyReference URI="#HelloWorldOutputBindingPolicy" /> 
       <soap:body use="literal" /> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="HelloWorldImplService"> 
     <wsdl:port binding="tns:HelloWorldImplServiceSoapBinding" name="HelloWorldImplPort"> 
      <soap:address location="http://localhost:8080/payment-engine/api/soap/hello" /> 
     </wsdl:port> 
    </wsdl:service> 
    <wsp:Policy wsu:Id="HelloWorldBindingPolicy"> 
     <wsp:ExactlyOne> 
      <wsp:All> 
       <sp:AsymmetricBinding> 
        <wsp:Policy> 
         <sp:InitiatorToken> 
          <wsp:Policy> 
           <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> 
            <wsp:Policy> 
             <sp:WssX509V3Token11 /> 
            </wsp:Policy> 
           </sp:X509Token> 
          </wsp:Policy> 
         </sp:InitiatorToken> 
         <sp:RecipientToken> 
          <wsp:Policy> 
           <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never"> 
            <wsp:Policy> 
             <sp:WssX509V3Token11 /> 
             <sp:RequireIssuerSerialReference /> 
            </wsp:Policy> 
           </sp:X509Token> 
          </wsp:Policy> 
         </sp:RecipientToken> 
         <sp:Layout> 
          <wsp:Policy> 
           <sp:Strict /> 
          </wsp:Policy> 
         </sp:Layout> 
         <sp:IncludeTimestamp /> 
         <sp:OnlySignEntireHeadersAndBody /> 
         <sp:AlgorithmSuite> 
          <wsp:Policy> 
           <sp:Basic128 /> 
          </wsp:Policy> 
         </sp:AlgorithmSuite> 
         <sp:EncryptSignature /> 
        </wsp:Policy> 
       </sp:AsymmetricBinding> 
       <sp:Wss11> 
        <wsp:Policy> 
         <sp:MustSupportRefIssuerSerial /> 
        </wsp:Policy> 
       </sp:Wss11> 
      </wsp:All> 
     </wsp:ExactlyOne> 
    </wsp:Policy> 
    <wsp:Policy wsu:Id="HelloWorldInputBindingPolicy"> 
     <wsp:ExactlyOne> 
      <wsp:All> 
       <sp:EncryptedParts> 
        <sp:Body /> 
       </sp:EncryptedParts> 
       <sp:SignedParts> 
        <sp:Body /> 
       </sp:SignedParts> 
      </wsp:All> 
     </wsp:ExactlyOne> 
    </wsp:Policy> 
    <wsp:Policy wsu:Id="HelloWorldOutputBindingPolicy"> 
     <wsp:ExactlyOne> 
      <wsp:All> 
       <sp:EncryptedParts> 
        <sp:Body /> 
       </sp:EncryptedParts> 
       <sp:SignedParts> 
        <sp:Body /> 
       </sp:SignedParts> 
      </wsp:All> 
     </wsp:ExactlyOne> 
    </wsp:Policy> 
</wsdl:definitions> 

Любая помощь будет очень признателен!

ответ

0

Успел получить эту половину работает с помощью следующего

HelloWorldImplService service = new HelloWorldImplService(); 
    HelloWorld port = service.getHelloWorldImplPort(); 

    Map<String, Object> ctx = ((BindingProvider) port).getRequestContext(); 
    ctx.put("ws-security.callback-handler", "com.example.payment.engine.soap.service.ClientPasswordCallback"); 
    ctx.put("ws-security.encryption.properties", "config/crypto.properties"); 
    ctx.put("ws-security.signature.properties", "config/crypto.properties"); 
    ctx.put("ws-security.encryption.username", "server"); 

    System.out.println(port.sayHello()); 
2

Я провел несколько дней в решении этого и дополнительные проблемы с Apache CXF 3.1.4. Дело в том, что сообщения об ошибках в CXF редко дают истинное представление о том, что исправить. Тот, который поставлен на карту, довольно типичен: он говорит о том, что имя не найдено, но не предоставляет фактическое значение, которое просматривается, а во-вторых, это не проблема в моем контексте.

я начинал от конфигурации CXF шины/политики XML/Spring на основе работы в тесте и прод в течение года, и, как: определение клиента:

SpringBusFactory bf = new SpringBusFactory(); 
URL busFile = MyClient.class.getResource("/wssec_policy.xml"); 
Bus bus = bf.createBus(busFile); 
BusFactory.setDefaultBus(bus); 

где wssec_policy.xml содержал JAXWS следующим образом:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:cxf="http://cxf.apache.org/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="...etc..."> 
<bean id="logOutbound" class="MyLoggingOutInterceptor"/> 
<bean id="logInbound" class="MyLoggingInInterceptor"/> 
<cxf:bus> 
    <cxf:outInterceptors><ref bean="logOutbound"/></cxf:outInterceptors> 
    <cxf:inInterceptors><ref bean="dumpMessageInterceptor"/><ref bean="logInbound"/></cxf:inInterceptors> 
    <cxf:features><cxf:logging/></cxf:features> 
</cxf:bus> 
<jaxws:client name="{http://some.domain/webservices}servicioSoap" createdFromAPI="true"> 
     <jaxws:properties> 
      <entry key="security.encryption.properties" value="etc/Client_Encrypt.properties"/> 
      <entry key="security.signature.properties" value="etc/Client_Sign.properties"/> 
     </jaxws:properties> 
    </jaxws:client> 
</beans> 

и где шифрование и signature.properties содержат WSS4J properties.

Мой вызов состоял в том, чтобы заставить это работать с CXF 3.1.4, BouncyCastle 1.52, Spring 4.2.4, на JRE 8; который не сделал этого, сначала стуча по ошибке, которую вы цитируете.

Я собрал код в клиенте POJO и начал сверлить исходный код CXF, чтобы найти истинную причину, и обнаружил, что настройка шины по умолчанию, как указано выше (которая ранее работала) больше не предоставляла jaxws: данных в слои WSS4J. Нет данных, следовательно, ошибка. Apache CXF предоставляет три способа настройки вашего WS- * стека (явные перехватчики, основанные на политиках с XML и основанные на политике через Java API). Чтобы решить проблему, я переключился на конфигурации на основе политик с помощью Java API следующим образом:

serviceGDS = new WSDL2Java_generated_Service(); 
portGDS = serviceGDS.getServiceGdsSoap(); 
Map<String, Object> ctx = ((javax.xml.ws.BindingProvider)portGDS).getRequestContext(); 
Properties encProps = new Properties(); 
encProps.load(new FileInputStream("etc/Client_Encrypt.properties")); 
ctx.put("security.encryption.properties", encProps); 
Properties signProps = new Properties(); 
signProps.load(new FileInputStream("etc/Client_Sign.properties")); 
ctx.put("security.signature.properties", signProps); 
// setting the props below once helped solving the error at stake 
ctx.put("security.signature.username","test_keypair"); 
ctx.put("security.encryption.username","gds_test_cert"); 

Последние два свойства были когда-то необходимо, чтобы прогрессировать в отладке, решая неправильные ключевые длины ошибки из-за отсутствия ключа псевдоним !!! Но в самом конце я заметил, что без них он работал! (они фактически дублируют псевдоним хранилища ключей в свойствах Client_Encrypt и Client_Sign).

Я тогда решил не найдено ни одного сертификата для шифрования ошибок, подавляя «org.apache.ws.security.crypto.merlin.keystore.Поставщик = BC»от Client_Encrypt и Client_Sign свойств (пока работал в прошлом версии).

Я решил отсутствует сертификат ошибки при переходе от PKCS12 типа хранилища ключей JKS . Я обнаружил, что keystore.load() не получать все содержащиеся в нем сертификаты ... с тем же p12 хранилищем я получаю результат изменяющееся в зависимости от контекста, в котором она называется ... багги действительно.

Я решил AsymmetricBinding не поддерживается, заметив, что повторное развертывание на реальном сервере (JBoss EAP7 в моем случае) никогда не работало, но когда развернутое приложение запускается вместе с сервером (следовательно, после перезагрузки сервера), он работает. Я сильно сомневаюсь в проблемах загрузчика классов.

Позвольте мне добавить, что я как-то переключился на JRE 7 (где устаревшее работает нормально), и ошибки были значительно разными (я подозреваю, что файлы конфигурации политики в JRE).

Еще одна серьезная проблема заключается в том, что все ошибки, будь то исключения на стороне клиента при обработке запроса или даже ответа, а также сбои на стороне сервера, все завернуты CXF в виде мыльных сбоев с краткими сообщениями об ошибках, что очень затрудняет понять, что происходит на самом деле. Единственный путь, который позволил мне продвинуться, - собрать необходимый клиентский код в POJO и отладить его с помощью библиотек исходного кода CXF и WSS4J (Eclipse/Maven извлекает исходный код для вас, пока вы используете отладчик и разворачиваете ... эффективный!)

 Смежные вопросы

  • Нет связанных вопросов^_^