【发布时间】: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