问题
My code runs successfully when tested within the Eclipse IDE.
I'm connecting to MS SharePoint 2010 via Web Services using the generated Copy.wsdl
When I deploy my code on the JBoss server (Running Adobe LifeCycle) my code receives a 401 Error.
Error:
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
Now if I purposely use the wrong login via the IDE I get this error:
com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized
Update:
So after more research it turns out J2EE support, well lack of, with NTLM is the cause. I've tried several solutions to no avail as of yet.
Code:
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));
}
Authenticator
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());
}
}
Get 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;
}
Call to upload file:
// make the call to upload
port.copyIntoItems("null", destinationUrlCollection, metadata, byteArray, longHolder, resultHolder);
回答1:
I am using CXF framework to create port. It will take care of all type of authentication. It is working in JBoss also.
It is simple to implement. Add CXF dependencies and use the following code to create port.
Sample Code :
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://<<IP>>/_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;
}
}
来源:https://stackoverflow.com/questions/25509111/java-jboss-401-error-on-sharepoint-2010-web-service