Created
October 15, 2018 18:42
-
-
Save nddipiazza/cfd8a6146faddb381db7d0bc7d52ebdd to your computer and use it in GitHub Desktop.
CXF SharePoint Soap API Tester with Kerberos Authentication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import crawler.common.sharepoint.stubs.sitedata.ArrayOfSList; | |
import crawler.common.sharepoint.stubs.sitedata.GetListCollectionResponse; | |
import crawler.common.sharepoint.stubs.sitedata.SList; | |
import crawler.common.sharepoint.stubs.sitedata.SiteData; | |
import crawler.common.sharepoint.stubs.sitedata.SiteDataSoap; | |
import org.apache.cxf.configuration.security.AuthorizationPolicy; | |
import org.apache.cxf.endpoint.Client; | |
import org.apache.cxf.frontend.ClientProxy; | |
import org.apache.cxf.transport.http.HTTPConduit; | |
import org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit; | |
import org.apache.cxf.transport.http.auth.HttpAuthHeader; | |
import org.apache.cxf.transport.http.auth.SpnegoAuthSupplier; | |
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; | |
import org.ietf.jgss.GSSName; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import javax.security.auth.login.AppConfigurationEntry; | |
import javax.security.auth.login.Configuration; | |
import javax.xml.namespace.QName; | |
import javax.xml.soap.SOAPMessage; | |
import javax.xml.ws.BindingProvider; | |
import javax.xml.ws.Holder; | |
import javax.xml.ws.Service; | |
import javax.xml.ws.handler.Handler; | |
import javax.xml.ws.handler.MessageContext; | |
import javax.xml.ws.handler.soap.SOAPHandler; | |
import javax.xml.ws.handler.soap.SOAPMessageContext; | |
import java.io.ByteArrayOutputStream; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
/** | |
* This example will invoke a web service on SharePoint 2013+ with optional kerberos auth. | |
*/ | |
public class SoapTester { | |
private static final Logger LOG = LoggerFactory.getLogger(SoapTester.class); | |
public static void main(String[] args) { | |
String endpointAddress = args[0]; | |
String keytabFilePath = args.length > 2 ? args[1] : null; | |
String principalName = args.length > 2 ? args[2] : null; | |
String servicePrincipalName = args.length > 3 ? args[3] : null; | |
if (!endpointAddress.endsWith("/")) { | |
endpointAddress += "/"; | |
} | |
endpointAddress += "_vti_bin/SiteData.asmx"; | |
final String endpointAddressFinal = endpointAddress; | |
Service service = Service.create(SiteData.SERVICE); | |
SiteDataSoap soap = service.getPort(SiteDataSoap.class); | |
NaiveSSLHelper.makeWebServiceClientTrustEveryone(soap); | |
BindingProvider bindingProvider = (BindingProvider) soap; | |
bindingProvider.getRequestContext().put(AsyncHTTPConduit.USE_ASYNC, | |
Boolean.TRUE); | |
bindingProvider.getRequestContext().put( | |
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress); | |
List<Handler> chain = bindingProvider.getBinding().getHandlerChain(); | |
chain.add(new SOAPHandler<SOAPMessageContext>() { | |
@Override | |
public boolean handleMessage(SOAPMessageContext context) { | |
String endpointAddress = (String) context.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); | |
SOAPMessage msg = context.getMessage(); | |
Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); | |
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { | |
msg.writeTo(out); | |
String str = new String(out.toByteArray()); | |
LOG.info("Sharepoint xml [" + endpointAddress + "]" + (outbound ? " (Outbound)" : " (Inbound)") + ": " + str); | |
} catch (Exception e) { | |
LOG.error("Cannot get soap xml from message ", e); | |
} | |
if (outbound.booleanValue()) { | |
try { | |
context.getMessage().setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8"); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
return true; | |
} | |
@Override | |
public boolean handleFault(SOAPMessageContext context) { | |
return true; | |
} | |
@Override | |
public void close(MessageContext context) { | |
} | |
@Override | |
public Set<QName> getHeaders() { | |
return null; | |
} | |
}); | |
bindingProvider.getBinding().setHandlerChain(chain); | |
Client client = ClientProxy.getClient(bindingProvider); | |
client.getEndpoint().put("org.apache.cxf.stax.maxChildElements", System.getProperty("org.apache.cxf.stax.maxChildElements") != null ? System.getProperty("org.apache.cxf.stax.maxChildElements") : "5000000"); | |
HTTPConduit http = (HTTPConduit) client.getConduit(); | |
NaiveSSLHelper.makeCxfWebServiceClientTrustEveryone(http); | |
AuthorizationPolicy authorization = new AuthorizationPolicy(); | |
authorization.setAuthorizationType(HttpAuthHeader.AUTH_TYPE_NEGOTIATE); | |
http.setAuthorization(authorization); | |
SpnegoAuthSupplier authSupplier = new SpnegoAuthSupplier(); | |
if (servicePrincipalName != null) { | |
authSupplier.setServicePrincipalName(servicePrincipalName); | |
authSupplier.setServiceNameType(GSSName.NT_HOSTBASED_SERVICE); | |
} | |
Map<String, String> loginConfig = new HashMap<>(); | |
loginConfig.put("useKeyTab", "true"); | |
loginConfig.put("storeKey", "true"); | |
loginConfig.put("refreshKrb5Config", "true"); | |
loginConfig.put("keyTab", keytabFilePath); | |
loginConfig.put("principal", principalName); | |
loginConfig.put("useTicketCache", "true"); | |
loginConfig.put("debug", String.valueOf(true)); | |
authSupplier.setLoginConfig(new Configuration() { | |
@Override | |
public AppConfigurationEntry[] getAppConfigurationEntry(String name) { | |
return new AppConfigurationEntry[] { | |
new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", | |
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, | |
loginConfig)}; | |
} | |
}); | |
http.setAuthSupplier(authSupplier); | |
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); | |
httpClientPolicy.setAllowChunking(false); | |
httpClientPolicy.setAutoRedirect(true); | |
http.setClient(httpClientPolicy); | |
Holder<ArrayOfSList> vLists = new Holder<>(); | |
Holder<Long> getListCollectionResult = new Holder<>(); | |
soap.getListCollectionAsync(getListCollectionResult, vLists, res -> { | |
try { | |
GetListCollectionResponse listCollectionResponse = res.get(); | |
ArrayOfSList arrayOfSList = listCollectionResponse.getVLists(); | |
LOG.info("Successfully got {} lists from {}", arrayOfSList.getSList().size(), endpointAddressFinal); | |
for (SList slist : arrayOfSList.getSList()) { | |
LOG.info("Successfully got list {}", slist.getTitle()); | |
} | |
System.exit(0); | |
} catch (Exception e) { | |
LOG.error("List collection response", e); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment