我正在尝试连接到使用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)
答案 0 :(得分:2)
专有的ws-policy标记http:NtlmAuthentication
存在问题。
问题是cxf试图自动满足开箱即用的ws-policy要求。由于此标记是专有的而非标准的,因此失败,因此例外。
从wsdl中删除此(整个)策略,并在没有此策略的情况下再次生成客户端。之后,ntlm身份验证应该可以工作。