【问题标题】:soap webservice client using apache cxf, for ntlm authentication使用 apache cxf 的 soap webservice 客户端,用于 ntlm 身份验证
【发布时间】:2014-08-21 06:13:47
【问题描述】:

我想开发一个使用 CXF 连接到SharePoint 的 SOAP 客户端。 身份验证方案是 NTLM

在计算机(正在运行 SOAP 客户端)的登录用户有权访问 SharePoint 的情况下,我被阻止了。 CXF soap 客户端始终使用登录用户。 我想指定一些其他用户凭据(不是登录的)。

由于 CXF 使用 in-JDK HttpURLConnection;我读到的关于HttpURLConnection 的内容是,当登录用户通过 NTLM 身份验证时,它会绕过指定的凭据。

已在 CXF 版本 2.7.11 上试用过代码。


我尝试过的解决方案:

1) 设置管道授权

String username = "user";     
String password = "password";    

JaxWsProxyfactoryBean factory1 = new JaxWsProxyfactoryBean();    
factory1.setServiceClass(WebsSoap.class);    
factory1.setAddress(url);    
factory1.setUsername(username);    
factory1.setPassword(password);

WebsSoap service = (WebsSoap) factory1.create();    
Client client = ClientProxy.getClient(service);    

HTTPconduit conduit = (HTTPconduit) client.getconduit();    
conduit.getAuthorization().setAuthorizationType("NTLM");    
conduit.getAuthorization().setUserName(username);    
conduit.getAuthorization().setPassword(password);

HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();  
httpClientPolicy.setConnectionTimeout(36000);  
httpClientPolicy.setAllowChunking(false);  
conduit.setClient(httpClientPolicy);  
        
service.getWeb(".");

问题:

这不适用于上面指定的场景,因为它始终使用登录凭据。当我指定无效凭据时,它不会失败。


2) AsyncHTTPConduit

另一种解决方案是使用AsyncHTTPConduit,它使用HttpAsyncClient 而不是HttpURLConnection。这是因为 HTTP 组件不会绕过指定的凭据,并且可以忽略登录用户(我已经使用 HttpClient 成功地通过测试客户端验证了这一点)。

下面是代码sn-p::

Bus bus = BusFactory.getDefaultBus();    
bus.setProperty( "use.async.http.conduit", "true" );
 
Client client = ClientProxy.getClient( service );    
HTTPConduit http = (HTTPConduit)client.getConduit();    
if ( http instanceof AsyncHTTPConduit ) {    
    AsyncHTTPConduit conduit = (AsyncHTTPConduit)http;    
    DefaultHttpAsyncClient defaultHttpAsyncClient;    
    try {    
        defaultHttpAsyncClient = conduit.getHttpAsyncClient();    
    }    
    catch ( IOException exception ) {    
        throw new RuntimeException( exception );    
    }    
    defaultHttpAsyncClient.getCredentialsProvider().setCredentials( AuthScope.ANY,
                        new NTCredentials( "username", "password", "", "domain" ) );         
    conduit.getClient().setAllowChunking( false );
    conduit.getClient().setAutoRedirect( true );
}

问题:

以上代码抛出错误:

在管道上检测到授权循环。

上面的代码快照显示了 DefaultHttpAsyncClient 现在已弃用 的用法,而将改用CloseableHttpAsyncClient。但是 CloseableHttpAsyncClient 不提供一种方法来指定凭据 到已经存在的 CloseableHttpAsyncClient 对象。不知道在这种情况下如何使用CloseableHttpAsyncClient


3) 其他解决方案

我尝试过的另一个解决方案是使用sun.net.www.protocol.http.ntlm.NTLMAuthenticationCallback,绕过登录用户身份验证,如here 所述。将此方法与上述解决方案#1 一起使用。这对有效/无效凭据按预期工作,并且代码绕过登录凭据:)。但是当我指定无效凭据时,我没有收到 HTTP 401 错误,而是收到了

无法发送消息,服务器已达到最大重试次数 20

我试图避免这种解决方案,因为它使用java的内部包,无法直接确定HTTP 401错误。

我可以做些什么来获得完整的解决方案?

【问题讨论】:

    标签: java cxf soap-client ntlm


    【解决方案1】:

    试试这个拦截器。这将避免自动身份验证。

    public class DisableAutomaticNTLMAuthOutInterceptor extends AbstractPhaseInterceptor<Message>
    {
        private boolean isFieldsAvailable;
    
        private Field tryTransparentNTLMProxyField;
    
        private Field tryTransparentNTLMServerField;
    
        public DisableAutomaticNTLMAuthOutInterceptor() {
            super(Phase.PRE_STREAM);
    
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Void run() {
                    try {
                        DisableAutomaticNTLMAuthOutInterceptor.this.tryTransparentNTLMServerField = HttpURLConnection.class.getDeclaredField("tryTransparentNTLMServer");
                        DisableAutomaticNTLMAuthOutInterceptor.this.tryTransparentNTLMServerField.setAccessible(true);
    
                        DisableAutomaticNTLMAuthOutInterceptor.this.tryTransparentNTLMProxyField = HttpURLConnection.class.getDeclaredField("tryTransparentNTLMProxy");
                        DisableAutomaticNTLMAuthOutInterceptor.this.tryTransparentNTLMProxyField.setAccessible(true);
                        DisableAutomaticNTLMAuthOutInterceptor.this.isFieldsAvailable = true;
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            });
        }
    
        @Override
        public void handleMessage(final Message message) throws Fault {
            if (this.isFieldsAvailable)
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    public Void run() {
                        try {
                            Object httpConnection = message.get("http.connection");
                            if (httpConnection != null) {
                                DisableAutomaticNTLMAuthOutInterceptor.this.processHttpConnection(message.get("http.connection"));
                            }
                        } catch (Throwable t) {
                            t.printStackTrace();
                        }
                        return null;
                    }
                });
    
        }
    
        private void processHttpConnection(Object httpConnection) throws IllegalArgumentException, IllegalAccessException {
    
            if (HttpURLConnection.class.isAssignableFrom(httpConnection.getClass())) {
                tryTransparentNTLMServerField.set(httpConnection, Boolean.FALSE);
                tryTransparentNTLMProxyField.set(httpConnection, Boolean.FALSE);
            } else {
                Field tempField = null;
                for (Field field : httpConnection.getClass().getDeclaredFields()) {
                    if (HttpURLConnection.class.isAssignableFrom(field.getType())) {
                        field.setAccessible(true);
                        tempField = field;
                        break;
                    }
                }
                if (tempField != null) {
                    processHttpConnection(tempField.get(httpConnection));
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      相关资源
      最近更新 更多