SharePoint 2010 Web服务上的Java JBoss 401错误
在Eclipse IDE中测试时,我的代码成功运行。
我正在使用生成的Copy.wsdl通过Web服务连接到MS SharePoint 2010
当我在JBoss服务器上部署代码(运行Adobe LifeCycle)时,我的代码收到401错误。
错误:
Caused by: org.jboss.ws.WSException: Invalid HTTP server response [401] - Unauthorized at org.jboss.ws.core.soap.SOAPMessageUnMarshallerHTTP.read(SOAPMessageUnMarshallerHTTP.java:75) at org.jboss.remoting.transport.http.HTTPClientInvoker.readResponse(HTTPClientInvoker.java:608) at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:402) at org.jboss.remoting.transport.http.HTTPClientInvoker.makeInvocation(HTTPClientInvoker.java:253) ... 156 more
现在,如果我故意通过IDE使用错误的登录,我会收到此错误:
com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized
更新:
所以经过更多的研究后发现J2EE支持,缺乏,NTLM就是原因。 我已经尝试了几种无法解决的解决方案。
码:
protected void initialize(String username, String password) throws Exception { System.out.println("initialize()..."); java.net.CookieManager cm = new java.net.CookieManager(); java.net.CookieHandler.setDefault(cm); Authenticator.setDefault(new SharepointAuthenticator(username, password)); }
认证
public class SharepointAuthenticator extends Authenticator { private String username = ""; private String password = ""; public SharepointAuthenticator(String username, String password) { this.username = username; this.password = password; System.out.println("Initializing Authentication"); } @Override public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password.toCharArray()); } }
获取SOAP
protected CopySoap getCopySoap(String username, String password, String wsdl, String endpoint) throws Exception { System.out.println("Creating a CopySoap instance..."); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); Copy service = new Copy(new URL(wsdl), new QName("http://schemas.microsoft.com/sharepoint/soap/", "Copy")); System.out.println("CopySoap 2"); CopySoap copySoap = service.getCopySoap(); System.out.println(endpoint + "\n" + wsdl); BindingProvider bp = (BindingProvider) copySoap; bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username); bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password); bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint); return copySoap; }
调用上传文件:
// make the call to upload port.copyIntoItems("null", destinationUrlCollection, metadata, byteArray, longHolder, resultHolder);
我正在使用CXF框架来创建端口。 它将负责所有类型的身份validation。 它也在JBoss中工作。
它很容易实现。 添加CXF依赖项并使用以下代码创建端口。
示例代码:
InvocationHandlerImpl.java
public class InvocationHandlerImpl implements InvocationHandler { CopySoap port; public InvocationHandlerImpl(CopySoap copySoap) { port = copySoap; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(port, args); } }
TrustingX509TrustManager.java
public class TrustingX509TrustManager implements X509TrustManager { /** * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() */ @Override public X509Certificate[] getAcceptedIssuers() { // return null will let jsse accept all certificates! return null; } /** * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType) */ @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { } /** * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType) */ @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { } }
SPCopyDriver.java
public class SPCopyDriver { public static void main(String[] args) { JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean(); proxyFactory.setServiceClass(CopySoap.class); proxyFactory.setUsername("domain\\username"); proxyFactory.setPassword("password"); proxyFactory.setAddress("https://<>/_vti_bin/Copy.asmx"); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setAutoRedirect(true); httpClientPolicy.setAllowChunking(false); Object port = proxyFactory.create(); Client client = ClientProxy.getClient(port); HTTPConduit httpConduit = (HTTPConduit) client.getConduit(); httpConduit.setClient(httpClientPolicy); TLSClientParameters tls = new TLSClientParameters(); tls.setDisableCNCheck(true); tls.setTrustManagers(new TrustManager[] { new TrustingX509TrustManager() }); httpConduit.setTlsClientParameters(tls); port = Proxy.newProxyInstance(SPCopyDriver.class.getClassLoader(), new Class[] { CopySoap.class }, new InvocationHandlerImpl((CopySoap) port)); CopySoap copySoap = (CopySoap) port; } }