java - Apache CXF 3.1.6 Web 服务客户端 - NTLM 身份验证

标签 java web-services cxf ntlm cxf-client

我正在尝试连接到通过 NTLM 进行身份验证的服务。我有使用 Maven cxf 插件 wsdl2java 生成的客户端。我遇到了一个异常(exception):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)

最佳答案

这是专有 ws-policy 标记 http:NtlmAuthentication 的问题。 问题是 cxf 尝试自动满足开箱即用的 ws-policy 要求。由于此标签是专有的且非标准的,因此它会失败,因此出现异常。

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

关于java - Apache CXF 3.1.6 Web 服务客户端 - NTLM 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38144832/

相关文章:

java - java中的粗体字符串而不是将该字符串发送到打印机

java - 如何在android studio中恢复到旧的包样式?

java - Jersey servlet 映射困惑

CXF 日志响应时间

java - UVa 的扫雷 (10189)

java - 桌面应用程序基准测试

java.net.UnknownHostException : Unable to resolve host "<url>": No address associated with hostname and End of input at character 0 of

asp.net - 从 Web 服务返回 XElement

java - 从 org.apache.cxf.binding.soap.SoapMessage 中提取信息

cxf - Kuali Rice远程API : removePrincipalFromRole failing silently