Apache CXF 3.1.6 webservice客户端 - NTLM身份验证

时间:2016-07-01 11:56:39

标签: java web-services cxf ntlm cxf-client

我正在尝试连接到使用NTLM进行身份验证的服务。我有使用maven cxf插件wsdl2java生成的客户端。我遇到了一个异常:org.apache.cxf.ws.policy.PolicyException:没有任何策略选择可以满足。也许还有另一种方法可以进行身份​​验证。

public class UFENTLM1Test {

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException, InstantiationException {
    System.out.println("UFE SERVICE TEST (NTLM No1 WRAPPER)");
    System.out.println("PARAMS: " + args[1] + " " + args[2] + " ");
    System.out.println("START");

    Authenticator.setDefault(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return (new PasswordAuthentication(args[1], args[2].toCharArray()));
        }
    });
    //LAMAccountAPI service = new LAMAccountAPI();

    URL url = LAMAccountAPI.class.getClassLoader().getResource("wsdl/ufe/ufe_account.wsdl");

    // TO AVOID SEIStub cannot be cast to ClientProxy
    LAMAccountAPI service = new LAMAccountAPI(url, LAMAccountAPI.SERVICE);
    Field delegateField = Service.class.getDeclaredField("delegate");
    delegateField.setAccessible(true);
    ServiceDelegate previousDelegate = (ServiceDelegate) delegateField.get(service);
    if (!previousDelegate.getClass().getName().contains("cxf")) {
        ServiceDelegate serviceDelegate = ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance())
                .createServiceDelegate(url, LAMAccountAPI.SERVICE, service.getClass());
        delegateField.set(service, serviceDelegate);
    }

    ILAMZarzadzanieKontem port = service.getBasicHttpBindingILAMZarzadzanieKontem();

    // Many various tryings
    Client client = ClientProxy.getClient(port);
    HTTPConduit http = (HTTPConduit) client.getConduit();
    http.getAuthorization().setUserName(args[1]);
    http.getAuthorization().setPassword(args[2]);
    AuthorizationPolicy policy = new AuthorizationPolicy();
    policy.setUserName(args[1]);
    policy.setPassword(args[2]);
    http.setAuthorization(policy);
    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
    httpClientPolicy.setConnectionTimeout(36000);
    httpClientPolicy.setAllowChunking(false);
    http.setClient(httpClientPolicy);

    List<Konto> accounts = null;
    try {
        accounts = port.pobierzKonta().getKonto();
    } catch (ILAMZarzadzanieKontemPobierzKontaSOAPExceptionFaultMessage | ILAMZarzadzanieKontemPobierzKontaDataConversionExceptionFaultMessage ilamZarzadzanieKontemPobierzKontaSOAPExceptionFaultMessage) {
        ilamZarzadzanieKontemPobierzKontaSOAPExceptionFaultMessage.printStackTrace();
    }
}

来自WSDL的策略定义:

<wsp:Policy wsu:Id="BasicHttpBinding_ILAMZarzadzanieKontem_policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <http:NtlmAuthentication xmlns:http="http://schemas.microsoft.com/ws/06/2004/policy/http"/>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>

最后,完整的堆栈跟踪:

UFE SERVICE TEST (NTLM No1 WRAPPER)
START
lip 01, 2016 2:38:20 PM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector]  selectAlternatives
WARNING: WSP0075: Policy assertion "{http://schemas.microsoft.com/ws/06/2004/policy/http}NtlmAuthentication" was evaluated as "UNKNOWN".
lip 01, 2016 2:38:20 PM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector]  selectAlternatives
WARNING: WSP0019: Suboptimal policy alternative selected on the client side with fitness "UNKNOWN".
lip 01, 2016 2:38:21 PM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
INFO: Creating Service {http://tempuri.org/}LAMAccountAPI from WSDL: file:/C:/dev/work/compfort/warta/3639/iiq-connector/target/classes/wsdl/ufe/ufe_account.wsdl
lip 01, 2016 2:38:22 PM org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl handleNoRegisteredBuilder
WARNING: No assertion builder for type {http://schemas.microsoft.com/ws/06/2004/policy/http}NtlmAuthentication registered.
Exception in thread "main" org.apache.cxf.ws.policy.PolicyException: None of the policy alternatives can be satisfied.
    at org.apache.cxf.ws.policy.EndpointPolicyImpl.chooseAlternative(EndpointPolicyImpl.java:172)
    at org.apache.cxf.ws.policy.EndpointPolicyImpl.finalizeConfig(EndpointPolicyImpl.java:146)
    at org.apache.cxf.ws.policy.EndpointPolicyImpl.initialize(EndpointPolicyImpl.java:142)
    at org.apache.cxf.ws.policy.PolicyEngineImpl.createEndpointPolicyInfo(PolicyEngineImpl.java:604)
    at org.apache.cxf.ws.policy.PolicyEngineImpl.getEndpointPolicy(PolicyEngineImpl.java:316)
    at org.apache.cxf.ws.policy.PolicyEngineImpl.getClientEndpointPolicy(PolicyEngineImpl.java:303)
    at org.apache.cxf.ws.policy.PolicyDataEngineImpl.getClientEndpointPolicy(PolicyDataEngineImpl.java:61)
    at org.apache.cxf.transport.http.HTTPConduit.updateClientPolicy(HTTPConduit.java:318)
    at org.apache.cxf.transport.http.HTTPConduit.updateClientPolicy(HTTPConduit.java:338)
    at org.apache.cxf.transport.http.HTTPConduit.getClient(HTTPConduit.java:873)
    at org.apache.cxf.transport.http.HTTPConduit.configureConduitFromEndpointInfo(HTTPConduit.java:360)
    at org.apache.cxf.transport.http.HTTPConduit.finalizeConfig(HTTPConduit.java:440)
    at org.apache.cxf.transport.http.HTTPTransportFactory.getConduit(HTTPTransportFactory.java:242)
    at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:226)
    at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:233)
    at org.apache.cxf.endpoint.AbstractConduitSelector.createConduit(AbstractConduitSelector.java:145)
    at org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:107)
    at org.apache.cxf.endpoint.UpfrontConduitSelector.selectConduit(UpfrontConduitSelector.java:77)
    at org.apache.cxf.endpoint.ClientImpl.getConduit(ClientImpl.java:845)
    at pl.warta.connector.ufe.test.UFENTLM1Test.main(UFENTLM1Test.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

1 个答案:

答案 0 :(得分:2)

专有的ws-policy标记http:NtlmAuthentication存在问题。 问题是cxf试图自动满足开箱即用的ws-policy要求。由于此标记是专有的而非标准的,因此失败,因此例外。

从wsdl中删除此(整个)策略,并在没有此策略的情况下再次生成客户端。之后,ntlm身份验证应该可以工作。