2012-08-22 6 views
10

Próbuję utworzyć klienta WS innych firm. Moja aplikacja działa na JBoss AS 6 (ze stosem Apache CXF 2.3.1). Wygenerowałem kod klienta według wsconsume (wsdl2java). Kiedy próbowałem połączyć WS się dostał wyjątek:Apache CXF - Żadna z opcji strategii nie może być spełniona

No assertion builder for type http://schemas.microsoft.com/ws/06/2004/policy/http}BasicAuthentication registered. 
Exception in thread "main" org.apache.cxf.ws.policy.PolicyException: None of the policy alternatives can be satisfied. 

Auth częścią WSDL wygląda następująco:

<wsp:Policy wsu:Id="abc_ssl_policy"> 
    <wsp:ExactlyOne> 
     <wsp:All> 
      <http:BasicAuthentication 
       xmlns:http="http://schemas.microsoft.com/ws/06/2004/policy/http" /> 
      <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> 
       </wsp:Policy> 
      </sp:TransportBinding> 
     </wsp:All> 
    </wsp:ExactlyOne> 
</wsp:Policy> 

kod Klient:

@WebServiceClient(name = "Abc", 
       wsdlLocation = "https://hiddendomain.com/abc/abc.svc?wsdl", 
       targetNamespace = "http://tempuri.org/")     
public class Abc extends Service { 

public final static URL WSDL_LOCATION; 

public final static QName SERVICE = new QName("http://tempuri.org/", "Abc"); 
public final static QName AbcSsl = new QName("http://tempuri.org/", "abc_ssl"); 
static { 

    Authenticator.setDefault(new Authenticator() { 
     @Override 
     protected PasswordAuthentication getPasswordAuthentication() { 
      return new PasswordAuthentication("user", "pas".toCharArray()); 
     } 

    }); 

    URL url = null; 
    try { 
     url = new URL("https://hiddendomain.com/abc/abc.svc?wsdl"); 

    } catch (MalformedURLException e) { 
     java.util.logging.Logger.getLogger(DistrInfo.class.getName()) 
      .log(java.util.logging.Level.INFO, 
       "Can not initialize the default wsdl from {0}", "..."); 
    } 
    WSDL_LOCATION = url; 
} 

jest wyjątek whe próbuję dostać Conduit :

Client client = ClientProxy.getClient(port); 
    HTTPConduit con = (HTTPConduit) client.getConduit(); <- exception 

I s To dlatego, że nie jest to standardowa polityka dla MS i potrzebuję odpowiedniego Intercertptora do obsługi tych zasad, ale czy ktoś może mi pokazać sposób, jak to zrobić?

dont nawet nie, gdzie mam umieścić moje HTTPS poświadczeń do dopuszczonego (nie mogę dostać przewód)

Odpowiedz

11

Problem zniknął gdy użyłem tego kodu:

import org.apache.cxf.endpoint.Client; 
import org.apache.cxf.frontend.ClientProxy; 
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; 
import org.apache.cxf.transport.http.HTTPConduit; 

... 

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); 

//factory.getInInterceptors().add(new LoggingInInterceptor()); 
//factory.getOutInterceptors().add(new LoggingOutInterceptor()); 

factory.setServiceClass(IAbc.class); 
factory.setAddress("https://hiddendomain.com/abc/abc.svc/soap"); <- must be /soap there, otherwise 404 

IAbc info = (IAbc) factory.create(); 

Client client = ClientProxy.getClient(info); 
HTTPConduit http = (HTTPConduit) client.getConduit(); 

http.getAuthorization().setUserName("user"); 
http.getAuthorization().setPassword("pass"); 

String abc = info.abc(); 
+1

Dzięki, że rozwiązać mój problem, jak również. Początkowo korzystałem z usługi HTTP, ale po przejściu na HTTPS dostałem przerażający wyjątek PolicyException. Początkowo zrobiłem 'MyService ss = new MyService (nowy adres URL (wsdlUrl), nowe QName (" http://tempuri.org/ "," MyService ")); IMyService port = ss.getBasicHttpBindingIMyService(); '. Teraz robię "JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass (IMyService.class); factory.setAddress (wsdlUrl.replace ("? wsdl", "")); Port IMyService = (IMyService) factory.create(); '. – neu242

+0

To było naprawdę pomocne! Dzięki!! –

+0

Otrzymuję ten sam problem ... podczas gdy kod działał w tomcat, ale kiedy wdrażam kod w jboss, otrzymuję ten błąd. czy możesz podzielić się pełnym kodem programu klienta. – aravind

1

Jesteś super. to rozwiązało mój problem wsse: policy security problem we wsdl. Teraz mogę zadzwonić do zabezpieczonej usługi za pomocą CXF.

muszę dodać następujących w moim kodu

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); 
    factory.setServiceClass(TicketServicePortType.class); 
    factory.setAddress("http://localhost:8090/services"); 
    TicketServicePortType port = (TicketServicePortType) factory.create(); 

    Client client = ClientProxy.getClient(port); 
    HTTPConduit http = (HTTPConduit) client.getConduit(); 

    http.getAuthorization().setUserName("user"); 
    http.getAuthorization().setPassword("password"); 


    Endpoint cxfEndpoint = client.getEndpoint(); 

    Map<String,Object> outProps = new HashMap<String,Object>(); 

    outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); 
    outProps.put(WSHandlerConstants.USER, "user"); 
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 
    outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, 
    ClientPasswordCallback.class.getName()); 

    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 
    cxfEndpoint.getOutInterceptors().add(wssOut); 
+0

1) lepiej jest użyć outProps.put (WSHandlerConstants.PW_CALLBACK_REF, new ClientPasswordCallback()); 2) inicjowanie nazwy użytkownika/hasła w http.getAuthorization() wydaje się być bezużyteczne ... – ursa

1

Dla mnie usuwania CXF wiązka z projektem pomogła natychmiast:

<dependency> 
    <groupId>org.apache.cxf</groupId> 
    <artifactId>cxf-bundle</artifactId> 
    <version>2.7.17</version> 
</dependency>