如何在使用 cxf 启动时将基本授权添加到 wsdl?

How to add Basic Authorization to a wsdl on startup with cxf?

我有一个 wsdl 客户端和自动生成的 类 cxf

wsdl 本身需要基本授权才能访问,因此我将以下内容添加到每个 BindingPort:

    Map<String, Object> requestContext = ((BindingProvider)sc).getRequestContext();
    requestContext.put(BindingProvider.USERNAME_PROPERTY, userName);
    requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);

问题:当 运行 web 服务客户端时首先评估。但在此之前,cxf 正在尝试初始化 wsdl 服务并尝试从 url.

获取 wsdl

如何获得基本授权?

Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
    at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:87)
    at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:218)
    at org.apache.cxf.jaxws.ServiceImpl.initialize(ServiceImpl.java:161)
    ... 58 more
Caused by: javax.wsdl.WSDLException: WSDLException (at /wsdl:definitions/wsdl:types/xsd:schema): faultCode=PARSER_ERROR: Problem parsing 'https://my.domain.com/MyService'.: java.io.IOException: Server returned HTTP response code: 401 for URL: https://my.domain.com/MyService
    at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(WSDLReaderImpl.java:2198)
    at com.ibm.wsdl.xml.WSDLReaderImpl.parseSchema(WSDLReaderImpl.java:830)
    at com.ibm.wsdl.xml.WSDLReaderImpl.parseSchema(WSDLReaderImpl.java:654)
    at com.ibm.wsdl.xml.WSDLReaderImpl.parseTypes(WSDLReaderImpl.java:610)
    at com.ibm.wsdl.xml.WSDLReaderImpl.parseDefinitions(WSDLReaderImpl.java:320)
    at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2352)
    at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2338)
    at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:229)
    at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:163)
    at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:85)
    ... 60 more
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: https://my.domain.com/MyService
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1839)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:646)
    at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:348)
    at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(WSDLReaderImpl.java:2188)
    ... 69 more

来自http://cxf.547215.n5.nabble.com/Retrive-WSDL-using-basic-authentication-td5724416.html

的解决方案
public class Authorization {

    public static void main(String[] args) throws Exception {
        String wsdl = "http://localhost/WebService/Service?wsdl";
        String username = "user";
        String password = "password";
        String method = "foo";

        Bus bus = CXFBusFactory.getThreadDefaultBus();
        MyHTTPConduitConfigurer conf = new MyHTTPConduitConfigurer(username, password);
        bus.setExtension(conf, HTTPConduitConfigurer.class); //important: do not use your implementation class, but the interface
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(bus);

        Client client = dcf.createClient(wsdl);

        Object[] res = client.invoke(method);

        System.out.println(Arrays.deepToString(res));
    }
}

class MyHTTPConduitConfigurer implements HTTPConduitConfigurer {

    private final String username;
    private final String password;

    public MyHTTPConduitConfigurer(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public void configure(String name, String address, HTTPConduit c) {
        AuthorizationPolicy ap = new AuthorizationPolicy();
        ap.setUserName(username);
        ap.setPassword(password);
        c.setAuthorization(ap);
    }
}