blob: 17863395fe012d7beb8969220de0a080bfa82482 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.superbiz.calculator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import junit.framework.TestCase;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(Arquillian.class)
public class CalculatorTest {
@Deployment(testable = false)
public static Archive<?> app() {
return ShrinkWrap.create(WebArchive.class, "app.war")
.addClasses(CalculatorWs.class, CalculatorImpl.class);
}
@ArquillianResource
private URL base;
/**
* Create a webservice client using wsdl url
*
* @throws Exception
*/
//START SNIPPET: webservice
@Test
public void remoteCallWithSslClient() throws Exception {
// create the service from the WSDL
final URL url = new URL(base.toExternalForm() + "webservices/CalculatorImpl?wsdl");
final QName calcServiceQName = new QName("http://superbiz.org/wsdl", "CalculatorWsService");
final Service calcService = Service.create(url, calcServiceQName);
assertNotNull(calcService);
// get the port for the service
final CalculatorWs calc = calcService.getPort(CalculatorWs.class);
// switch the target URL for invocation to HTTPS
((BindingProvider) calc).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://localhost:8443/app/webservices/CalculatorImpl");
// add the SSL Client certificate, set the trust store and the hostname verifier
setupTLS(calc);
// call the remote JAX-WS webservice
assertEquals(10, calc.sum(4, 6));
assertEquals(12, calc.multiply(3, 4));
}
//END SNIPPET: webservice
public static void setupTLS(final Object port) throws GeneralSecurityException, IOException {
final HTTPConduit httpConduit = (HTTPConduit) ClientProxy.getClient(port).getConduit();
final TLSClientParameters tlsCP = new TLSClientParameters();
final String storePassword = "keystorePass";
final String keyPassword = "clientPassword";
final KeyStore keyStore = KeyStore.getInstance("jks");
final String keyStoreLoc = "META-INF/clientStore.jks";
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(keyStoreLoc), storePassword.toCharArray());
// set the key managers from the Java KeyStore we just loaded
final KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);
tlsCP.setKeyManagers(myKeyManagers);
tlsCP.setCertAlias("clientalias"); // in case there is multiple certs in the keystore, make sure we pick the one we want
// Create a trust manager that does not validate certificate chains
// this should not be done in production. It's recommended to create a cacerts with the certificate chain or
// to rely on a well known CA such as Verisign which is already available in the JVM
TrustManager[] trustAllCerts = getTrustManagers();
tlsCP.setTrustManagers(trustAllCerts);
// don't check the host name of the certificate to match the server (running locally)
// this should not be done on a real production system
tlsCP.setHostnameVerifier((s, sslSession) -> true);
httpConduit.setTlsClientParameters(tlsCP);
}
private static TrustManager[] getTrustManagers() throws NoSuchAlgorithmException, KeyStoreException {
return new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
}
private static KeyManager[] getKeyManagers(KeyStore keyStore, String keyPassword) throws GeneralSecurityException, IOException {
String alg = KeyManagerFactory.getDefaultAlgorithm();
char[] keyPass = keyPassword != null ? keyPassword.toCharArray() : null;
KeyManagerFactory fac = KeyManagerFactory.getInstance(alg);
fac.init(keyStore, keyPass);
return fac.getKeyManagers();
}
}