This is an automated email from the ASF dual-hosted git repository. jlmonteiro pushed a commit to branch TOMEE-2525_SSL-client-required in repository https://gitbox.apache.org/repos/asf/tomee.git
commit 89b5a859b6dc17d5151fabb868272be92ad32457 Author: Jean-Louis Monteiro <[email protected]> AuthorDate: Wed May 22 11:37:25 2019 +0200 TOMEE-2525 Example for JAX-WS with SSL Client required --- examples/pom.xml | 1 + examples/webservice-ssl-client-cert/README.adoc | 394 +++++++++++++++++++++ .../create-keystores.xml | 202 +++++++++++ .../keys/generateKeyPair.bat | 31 ++ .../keys/generateServerKey.bat | 24 ++ examples/webservice-ssl-client-cert/pom.xml | 138 ++++++++ .../org/superbiz/calculator/CalculatorImpl.java | 49 +++ .../java/org/superbiz/calculator/CalculatorWs.java | 35 ++ .../src/main/resources/META-INF/ejb-jar.xml | 19 + .../src/main/resources/META-INF/openejb-jar.xml | 29 ++ .../src/test/conf/server.xml | 46 +++ .../org/superbiz/calculator/CalculatorTest.java | 154 ++++++++ .../src/test/resources/META-INF/placeholder | 3 + .../src/test/resources/arquillian.xml | 46 +++ 14 files changed, 1171 insertions(+) diff --git a/examples/pom.xml b/examples/pom.xml index 8e5a57d..b4591a7 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -175,6 +175,7 @@ <module>webservice-attachments</module> <module>webservice-inheritance</module> <module>webservice-security</module> + <module>webservice-ssl-client-cert</module> <module>webservice-ws-security</module> <module>webservice-ws-with-resources-config</module> <module>webservice-handlerchain</module> diff --git a/examples/webservice-ssl-client-cert/README.adoc b/examples/webservice-ssl-client-cert/README.adoc new file mode 100644 index 0000000..c82a36e --- /dev/null +++ b/examples/webservice-ssl-client-cert/README.adoc @@ -0,0 +1,394 @@ +:index-group: Web Services :jbake-type: page :jbake-status: +status=published = Webservice SSL Client Certificate + +_Help us document this example! Click the blue pencil icon in the upper +right to edit this page._ + +This example is intended to show how to setup TomEE with HTTPS with SSL Client required. +It is very common to use HTTPS on the server side to authenticate the server. +But it's not so common to get the server to require client authentication using SSL. + +This example with generate keypairs for both the client and the server and create the 2 keystores (server and client). + +The HTTPS connector in the `server.xml` shows how to setup up the server side. + +The test case shows how to interact with CXF API in order to configure the client side. + + +== CalculatorImpl + +.... +package org.superbiz.calculator; + +import javax.annotation.security.DeclareRoles; +import javax.annotation.security.RolesAllowed; +import javax.ejb.Stateless; +import javax.jws.WebService; + +/** + * This is an EJB 3 style pojo stateless session bean + * Every stateless session bean implementation must be annotated + * using the annotation @Stateless + * This EJB has a single interface: CalculatorWs a webservice interface. + */ +//START SNIPPET: code +@DeclareRoles(value = {"Administrator"}) +@Stateless +@WebService( + portName = "CalculatorPort", + serviceName = "CalculatorWsService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.calculator.CalculatorWs") +public class CalculatorImpl implements CalculatorWs { + + public int sum(int add1, int add2) { + return add1 + add2; + } + + public int multiply(int mul1, int mul2) { + return mul1 * mul2; + } + +} +//END SNIPPET: code +.... + +== CalculatorWs + +.... +package org.superbiz.calculator; + +import javax.jws.WebService; + +//START SNIPPET: code +/** + * This is an EJB 3 webservice interface + * A webservice interface must be annotated with the @Local + * annotation. + */ +@WebService(targetNamespace = "http://superbiz.org/wsdl") +public interface CalculatorWs { + + int sum(int add1, int add2); + + int multiply(int mul1, int mul2); +} +//END SNIPPET: code +.... + +== ejb-jar.xml + +.... +<ejb-jar/> +.... + +== openejb-jar.xml + +.... +<openejb-jar xmlns="http://tomee.apache.org/xml/ns/openejb-jar-2.2"> + <enterprise-beans> + <session> + <ejb-name>CalculatorImpl</ejb-name> + <web-service-security> + <security-realm-name/> + <transport-guarantee>CONFIDENTIAL</transport-guarantee> + </web-service-security> + </session> + </enterprise-beans> +</openejb-jar> +.... + +== CalculatorTest + +.... +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(); + } + +} +.... + +== Running + +.... +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.calculator.CalculatorTest +mai 22, 2019 11:28:28 AM org.apache.openejb.arquillian.common.Setup findHome +INFOS: Unable to find home in: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee +mai 22, 2019 11:28:28 AM org.apache.openejb.arquillian.common.MavenCache getArtifact +INFOS: Downloading org.apache.tomee:apache-tomee:8.0.0-SNAPSHOT:zip:plus please wait... +mai 22, 2019 11:28:28 AM org.apache.openejb.arquillian.common.Zips unzip +INFOS: Extracting '/Users/jlmonteiro/.m2/repository/org/apache/tomee/apache-tomee/8.0.0-SNAPSHOT/apache-tomee-8.0.0-SNAPSHOT-plus.zip' to '/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee' +mai 22, 2019 11:28:29 AM org.apache.tomee.arquillian.remote.RemoteTomEEContainer configure +INFOS: Downloaded container to: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT +22-May-2019 11:28:30.050 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke La librairie Apache Tomcat Native basée sur APR qui permet des performances optimales dans les environnements de production n'a pas été trouvée sur le java.library.path: [/Users/jlmonteiro/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.] +22-May-2019 11:28:30.373 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Initialisation du gestionnaire de protocole ["http-nio-64661"] +22-May-2019 11:28:30.408 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Initialisation du gestionnaire de protocole ["https-jsse-nio-8443"] +mai 22, 2019 11:28:30 AM org.apache.openejb.client.EventLogger log +INFOS: RemoteInitialContextCreated{providerUri=http://localhost:64661/tomee/ejb} +22-May-2019 11:28:30.724 INFOS [main] org.apache.openejb.util.OptionsLog.info Using 'tomee.remote.support=true' +22-May-2019 11:28:30.734 INFOS [main] org.apache.openejb.util.OptionsLog.info Using 'openejb.jdbc.datasource-creator=org.apache.tomee.jdbc.TomEEDataSourceCreator' +22-May-2019 11:28:30.856 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> ******************************************************************************** +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> OpenEJB http://tomee.apache.org/ +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> Startup: Wed May 22 11:28:30 CEST 2019 +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> Copyright 1999-2018 (C) Apache OpenEJB Project, All Rights Reserved. +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> Version: 8.0.0-SNAPSHOT +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> Build date: 20190522 +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> Build time: 09:42 +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> ******************************************************************************** +22-May-2019 11:28:30.857 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> openejb.home = /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT +22-May-2019 11:28:30.858 INFOS [main] org.apache.openejb.OpenEJB$Instance.<init> openejb.base = /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT +22-May-2019 11:28:30.860 INFOS [main] org.apache.openejb.cdi.CdiBuilder.initializeOWB Created new singletonService org.apache.openejb.cdi.ThreadSingletonServiceImpl@1c1bbc4e +22-May-2019 11:28:30.863 INFOS [main] org.apache.openejb.cdi.CdiBuilder.initializeOWB Succeeded in installing singleton service +22-May-2019 11:28:30.897 INFOS [main] org.apache.openejb.config.ConfigurationFactory.init TomEE configuration file is '/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT/conf/tomee.xml' +22-May-2019 11:28:30.933 INFOS [main] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=Tomcat Security Service, type=SecurityService, provider-id=Tomcat Security Service) +22-May-2019 11:28:30.935 INFOS [main] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +22-May-2019 11:28:30.937 INFOS [main] org.apache.openejb.util.OptionsLog.info Using 'openejb.system.apps=true' +22-May-2019 11:28:30.939 INFOS [main] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container) +22-May-2019 11:28:30.957 INFOS [main] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating TransactionManager(id=Default Transaction Manager) +22-May-2019 11:28:31.003 INFOS [main] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating SecurityService(id=Tomcat Security Service) +22-May-2019 11:28:31.018 INFOS [main] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Container(id=Default Singleton Container) +22-May-2019 11:28:31.033 INFOS [main] org.apache.openejb.assembler.classic.Assembler.createApplication Assembling app: openejb +22-May-2019 11:28:31.087 INFOS [main] org.apache.openejb.util.OptionsLog.info Using 'openejb.jndiname.format={deploymentId}{interfaceType.openejbLegacyName}' +22-May-2019 11:28:31.095 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=openejb/DeployerBusinessRemote) --> Ejb(deployment-id=openejb/Deployer) +22-May-2019 11:28:31.095 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=global/openejb/openejb/openejb/Deployer!org.apache.openejb.assembler.Deployer) --> Ejb(deployment-id=openejb/Deployer) +22-May-2019 11:28:31.096 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=global/openejb/openejb/openejb/Deployer) --> Ejb(deployment-id=openejb/Deployer) +22-May-2019 11:28:31.097 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=openejb/ConfigurationInfoBusinessRemote) --> Ejb(deployment-id=openejb/ConfigurationInfo) +22-May-2019 11:28:31.097 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=global/openejb/openejb/openejb/Deployer!org.apache.openejb.assembler.classic.cmd.ConfigurationInfo) --> Ejb(deployment-id=openejb/ConfigurationInfo) +22-May-2019 11:28:31.099 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=MEJB) --> Ejb(deployment-id=MEJB) +22-May-2019 11:28:31.099 INFOS [main] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=global/openejb/openejb/openejb/Deployer!javax.management.j2ee.ManagementHome) --> Ejb(deployment-id=MEJB) +22-May-2019 11:28:31.106 INFOS [main] org.apache.openejb.assembler.classic.Assembler.startEjbs Created Ejb(deployment-id=MEJB, ejb-name=openejb/Deployer, container=Default Singleton Container) +22-May-2019 11:28:31.107 INFOS [main] org.apache.openejb.assembler.classic.Assembler.startEjbs Created Ejb(deployment-id=openejb/ConfigurationInfo, ejb-name=openejb/Deployer, container=Default Singleton Container) +22-May-2019 11:28:31.109 INFOS [main] org.apache.openejb.assembler.classic.Assembler.startEjbs Created Ejb(deployment-id=openejb/Deployer, ejb-name=openejb/Deployer, container=Default Singleton Container) +22-May-2019 11:28:31.109 INFOS [main] org.apache.openejb.assembler.classic.Assembler.startEjbs Started Ejb(deployment-id=MEJB, ejb-name=openejb/Deployer, container=Default Singleton Container) +22-May-2019 11:28:31.109 INFOS [main] org.apache.openejb.assembler.classic.Assembler.startEjbs Started Ejb(deployment-id=openejb/ConfigurationInfo, ejb-name=openejb/Deployer, container=Default Singleton Container) +22-May-2019 11:28:31.109 INFOS [main] org.apache.openejb.assembler.classic.Assembler.startEjbs Started Ejb(deployment-id=openejb/Deployer, ejb-name=openejb/Deployer, container=Default Singleton Container) +22-May-2019 11:28:31.115 INFOS [main] org.apache.openejb.assembler.classic.Assembler.deployMBean Deployed MBean(openejb.user.mbeans:application=openejb,group=org.apache.openejb.assembler.monitoring,name=JMXDeployer) +22-May-2019 11:28:31.117 INFOS [main] org.apache.openejb.assembler.classic.Assembler.createApplication Deployed Application(path=openejb) +22-May-2019 11:28:31.151 INFOS [main] org.apache.openejb.server.ServiceManager.initServer Creating ServerService(id=cxf) +22-May-2019 11:28:31.282 INFOS [main] org.apache.openejb.server.ServiceManager.initServer Creating ServerService(id=cxf-rs) +22-May-2019 11:28:31.321 INFOS [main] org.apache.openejb.server.SimpleServiceManager.start ** Bound Services ** +22-May-2019 11:28:31.321 INFOS [main] org.apache.openejb.server.SimpleServiceManager.printRow NAME IP PORT +22-May-2019 11:28:31.322 INFOS [main] org.apache.openejb.server.SimpleServiceManager.start ------- +22-May-2019 11:28:31.322 INFOS [main] org.apache.openejb.server.SimpleServiceManager.start Ready! +22-May-2019 11:28:31.322 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke L'initialisation du serveur a pris [1 451] millisecondes +22-May-2019 11:28:31.330 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Démarrage du service [Catalina] +22-May-2019 11:28:31.330 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Démarrage du moteur de Servlets: [Apache Tomcat (TomEE)/9.0.20 (8.0.0-SNAPSHOT)] +22-May-2019 11:28:31.375 INFOS [main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Impossible de fixer la propriété [clearReferencesRmiTargets] du chargeur de classes de l'application web à [true] car cette propriété n'existe pas +22-May-2019 11:28:31.375 INFOS [main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Impossible de fixer la propriété [clearReferencesObjectStreamClassCaches] du chargeur de classes de l'application web à [true] car cette propriété n'existe pas +22-May-2019 11:28:31.375 INFOS [main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Impossible de fixer la propriété [clearReferencesObjectStreamClassCaches] du chargeur de classes de l'application web à [true] car cette propriété n'existe pas +22-May-2019 11:28:31.375 INFOS [main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Impossible de fixer la propriété [clearReferencesThreadLocals] du chargeur de classes de l'application web à [true] car cette propriété n'existe pas +22-May-2019 11:28:31.405 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Démarrage du gestionnaire de protocole ["http-nio-64661"] +22-May-2019 11:28:31.416 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Démarrage du gestionnaire de protocole ["https-jsse-nio-8443"] +22-May-2019 11:28:31.422 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Le démarrage du serveur a pris [99] millisecondes +22-May-2019 11:28:31.612 INFOS [http-nio-64661-exec-3] org.apache.openejb.util.JarExtractor.extract Extracting jar: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app.war +22-May-2019 11:28:31.617 INFOS [http-nio-64661-exec-3] org.apache.openejb.util.JarExtractor.extract Extracted path: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app +22-May-2019 11:28:31.617 INFOS [http-nio-64661-exec-3] org.apache.tomee.catalina.TomcatWebAppBuilder.deployWebApps using default host: localhost +22-May-2019 11:28:31.618 INFOS [http-nio-64661-exec-3] org.apache.tomee.catalina.TomcatWebAppBuilder.init ------------------------- localhost -> /app +22-May-2019 11:28:31.619 INFOS [http-nio-64661-exec-3] org.apache.openejb.util.OptionsLog.info Using 'openejb.session.manager=org.apache.tomee.catalina.session.QuickSessionManager' +22-May-2019 11:28:31.730 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.ConfigurationFactory.configureApplication Configuring enterprise application: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app +22-May-2019 11:28:31.824 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.InitEjbDeployments.deploy Auto-deploying ejb CalculatorImpl: EjbDeployment(deployment-id=CalculatorImpl) +22-May-2019 11:28:31.832 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +22-May-2019 11:28:31.833 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.AutoConfig.createContainer Auto-creating a container for bean CalculatorImpl: Container(type=STATELESS, id=Default Stateless Container) +22-May-2019 11:28:31.833 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Container(id=Default Stateless Container) +22-May-2019 11:28:31.840 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +22-May-2019 11:28:31.841 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.AutoConfig.createContainer Auto-creating a container for bean app.Comp168386325: Container(type=MANAGED, id=Default Managed Container) +22-May-2019 11:28:31.841 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Container(id=Default Managed Container) +22-May-2019 11:28:31.848 INFOS [http-nio-64661-exec-3] org.apache.openejb.core.managed.SimplePassivater.init Using directory /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT/temp for stateful session passivation +22-May-2019 11:28:31.876 INFOS [http-nio-64661-exec-3] org.apache.openejb.config.AppInfoBuilder.build Enterprise application "/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app" loaded. +22-May-2019 11:28:31.876 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.Assembler.createApplication Assembling app: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app +22-May-2019 11:28:31.892 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=CalculatorImplLocal) --> Ejb(deployment-id=CalculatorImpl) +22-May-2019 11:28:31.892 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=global/app/CalculatorImpl!org.superbiz.calculator.CalculatorWs) --> Ejb(deployment-id=CalculatorImpl) +22-May-2019 11:28:31.893 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.JndiBuilder.bind Jndi(name=global/app/CalculatorImpl) --> Ejb(deployment-id=CalculatorImpl) +22-May-2019 11:28:31.912 INFOS [http-nio-64661-exec-3] org.apache.openejb.cdi.CdiBuilder.initSingleton Existing thread singleton service in SystemInstance(): org.apache.openejb.cdi.ThreadSingletonServiceImpl@1c1bbc4e +22-May-2019 11:28:31.999 INFOS [http-nio-64661-exec-3] org.apache.openejb.cdi.OpenEJBLifecycle.startApplication OpenWebBeans Container is starting... +22-May-2019 11:28:32.004 INFOS [http-nio-64661-exec-3] org.apache.webbeans.plugins.PluginLoader.startUp Adding OpenWebBeansPlugin : [CdiPlugin] +22-May-2019 11:28:32.007 INFOS [http-nio-64661-exec-3] org.apache.openejb.cdi.CdiScanner.handleBda Using annotated mode for file:/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app/WEB-INF/classes/ looking all classes to find CDI beans, maybe think to add a beans.xml if not there or add the jar to exclusions.list +22-May-2019 11:28:32.620 INFOS [http-nio-64661-exec-3] org.apache.webbeans.config.BeansDeployer.validateInjectionPoints All injection points were validated successfully. +22-May-2019 11:28:32.629 INFOS [http-nio-64661-exec-3] org.apache.openejb.cdi.OpenEJBLifecycle.startApplication OpenWebBeans Container has started, it took 629 ms. +22-May-2019 11:28:32.634 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.Assembler.startEjbs Created Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl, container=Default Stateless Container) +22-May-2019 11:28:32.646 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.Assembler.startEjbs Started Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl, container=Default Stateless Container) +22-May-2019 11:28:33.094 INFOS [http-nio-64661-exec-3] org.apache.openejb.server.webservices.WsService.deployApp Webservice(wsdl=http://localhost:64661/app/webservices/CalculatorImpl, qname={http://superbiz.org/wsdl}CalculatorWsService) --> Ejb(id=CalculatorImpl) +22-May-2019 11:28:33.094 INFOS [http-nio-64661-exec-3] org.apache.openejb.assembler.classic.Assembler.createApplication Deployed Application(path=/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app) +22-May-2019 11:28:33.200 INFOS [http-nio-64661-exec-3] org.apache.myfaces.ee.MyFacesContainerInitializer.onStartup Using org.apache.myfaces.ee.MyFacesContainerInitializer +22-May-2019 11:28:33.222 INFOS [http-nio-64661-exec-3] org.apache.myfaces.ee.MyFacesContainerInitializer.onStartup Added FacesServlet with mappings=[/faces/*, *.jsf, *.faces, *.xhtml] +22-May-2019 11:28:33.252 INFOS [http-nio-64661-exec-3] org.apache.jasper.servlet.TldScanner.scanJars Au moins un fichier JAR a été analysé pour trouver des TLDs mais il n'en contenait pas, le mode "debug" du journal peut être activé pour obtenir une liste complète de JAR scannés sans succès; éviter d'analyser des JARs inutilement peut améliorer sensiblement le temps de démarrage et le temps de compilation des JSPs +22-May-2019 11:28:33.258 INFOS [http-nio-64661-exec-3] org.apache.tomee.myfaces.TomEEMyFacesContainerInitializer.addListener Installing <listener>org.apache.myfaces.webapp.StartupServletContextListener</listener> +22-May-2019 11:28:33.316 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.DefaultFacesConfigurationProvider.getStandardFacesConfig Reading standard config META-INF/standard-faces-config.xml +22-May-2019 11:28:33.527 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.DefaultFacesConfigurationProvider.getClassloaderFacesConfig Reading config : jar:file:/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT/lib/openwebbeans-el22-2.0.9.jar!/META-INF/faces-config.xml +22-May-2019 11:28:33.528 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.DefaultFacesConfigurationProvider.getClassloaderFacesConfig Reading config : jar:file:/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT/lib/openwebbeans-jsf-2.0.9.jar!/META-INF/faces-config.xml +22-May-2019 11:28:33.656 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.LogMetaInfUtils.logArtifact Artifact 'myfaces-api' was found in version '2.3.3' from path 'file:/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT/lib/myfaces-api-2.3.3.jar' +22-May-2019 11:28:33.656 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.LogMetaInfUtils.logArtifact Artifact 'myfaces-impl' was found in version '2.3.3' from path 'file:/Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/tomee/apache-tomee-plus-8.0.0-SNAPSHOT/lib/myfaces-impl-2.3.3.jar' +22-May-2019 11:28:33.666 INFOS [http-nio-64661-exec-3] org.apache.myfaces.util.ExternalSpecifications.isCDIAvailable MyFaces CDI support enabled +22-May-2019 11:28:33.667 INFOS [http-nio-64661-exec-3] org.apache.myfaces.spi.impl.DefaultInjectionProviderFactory.getInjectionProvider Using InjectionProvider org.apache.myfaces.spi.impl.CDIAnnotationDelegateInjectionProvider +22-May-2019 11:28:33.711 INFOS [http-nio-64661-exec-3] org.apache.myfaces.util.ExternalSpecifications.isBeanValidationAvailable MyFaces Bean Validation support enabled +22-May-2019 11:28:33.737 INFOS [http-nio-64661-exec-3] org.apache.myfaces.application.ApplicationImpl.getProjectStage Couldn't discover the current project stage, using Production +22-May-2019 11:28:33.737 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.FacesConfigurator.handleSerialFactory Serialization provider : class org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory +22-May-2019 11:28:33.742 INFOS [http-nio-64661-exec-3] org.apache.myfaces.config.annotation.DefaultLifecycleProviderFactory.getLifecycleProvider Using LifecycleProvider org.apache.myfaces.config.annotation.Tomcat7AnnotationLifecycleProvider +22-May-2019 11:28:33.763 INFOS [http-nio-64661-exec-3] org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces ServletContext initialized. +22-May-2019 11:28:33.767 INFOS [http-nio-64661-exec-3] org.apache.myfaces.view.facelets.ViewPoolProcessor.initialize org.apache.myfaces.CACHE_EL_EXPRESSIONS web config parameter is set to "noCache". To enable view pooling this param must be set to "alwaysRecompile". View Pooling disabled. +22-May-2019 11:28:33.778 INFOS [http-nio-64661-exec-3] org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized MyFaces Core has started, it took [517] ms. +mai 22, 2019 11:28:34 AM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL +INFOS: Creating Service {http://superbiz.org/wsdl}CalculatorWsService from WSDL: http://localhost:64661/app/webservices/CalculatorImpl?wsdl +mai 22, 2019 11:28:34 AM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL +INFOS: Creating Service {http://superbiz.org/wsdl}CalculatorWsService from WSDL: http://localhost:64661/app/webservices/CalculatorImpl?wsdl +mai 22, 2019 11:28:35 AM org.apache.openejb.client.EventLogger log +INFOS: RemoteInitialContextCreated{providerUri=http://localhost:64661/tomee/ejb} +22-May-2019 11:28:35.386 INFOS [http-nio-64661-exec-6] org.apache.openejb.assembler.classic.Assembler.destroyApplication Undeploying app: /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app +mai 22, 2019 11:28:35 AM org.apache.openejb.arquillian.common.TomEEContainer undeploy +INFOS: cleaning /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app.war +mai 22, 2019 11:28:35 AM org.apache.openejb.arquillian.common.TomEEContainer undeploy +INFOS: cleaning /Users/apache/tomee/examples/webservice-ssl-client-cert/target/test/app/0/app +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.519 sec +22-May-2019 11:28:35.570 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Une commande d'arrêt valide a été reçue sur le port d'arrêt, arrêt de l'instance du serveur +22-May-2019 11:28:35.570 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Le gestionnaire de protocole ["http-nio-64661"] est mis en pause +22-May-2019 11:28:35.581 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Le gestionnaire de protocole ["https-jsse-nio-8443"] est mis en pause +22-May-2019 11:28:35.588 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Arrêt du service [Catalina] +22-May-2019 11:28:35.589 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Arrêt du gestionnaire de protocole ["http-nio-64661"] +22-May-2019 11:28:35.591 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Arrêt du gestionnaire de protocole ["https-jsse-nio-8443"] +22-May-2019 11:28:35.592 INFOS [main] org.apache.openejb.server.SimpleServiceManager.stop Stopping server services +22-May-2019 11:28:35.600 INFOS [main] org.apache.openejb.assembler.classic.Assembler.destroyApplication Undeploying app: openejb +22-May-2019 11:28:35.601 GRAVE [main] org.apache.openejb.core.singleton.SingletonInstanceManager.undeploy Unable to unregister MBean openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,EJBModule=openejb,SingletonSessionBean=openejb/Deployer,name=openejb/Deployer,j2eeType=Invocations +22-May-2019 11:28:35.601 GRAVE [main] org.apache.openejb.core.singleton.SingletonInstanceManager.undeploy Unable to unregister MBean openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,EJBModule=openejb,SingletonSessionBean=openejb/Deployer,name=openejb/Deployer,j2eeType=Invocations +22-May-2019 11:28:35.611 INFOS [main] sun.reflect.NativeMethodAccessorImpl.invoke Destruction du gestionnaire de protocole ["http-nio-64661"] +22-May-2019 11:28:35.611 INFOS [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Destruction du gestionnaire de protocole ["https-jsse-nio-8443"] + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +.... diff --git a/examples/webservice-ssl-client-cert/create-keystores.xml b/examples/webservice-ssl-client-cert/create-keystores.xml new file mode 100644 index 0000000..03c054d --- /dev/null +++ b/examples/webservice-ssl-client-cert/create-keystores.xml @@ -0,0 +1,202 @@ +<?xml version="1.0"?> +<!-- + + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + +--> + +<project default="run" name="create keystores et al"> + + <!-- first create our properties --> + <condition property="is.ibm.jdk"> + <available classname="com.ibm.crypto.tools.KeyTool"/> + </condition> + <condition property="is.sun.jdk" value="sun.security.tools.KeyTool"> + <available classname="sun.security.tools.KeyTool"/> + </condition> + <condition property="is.sun.jdk" value="sun.security.tools.keytool.Main"> + <available classname="sun.security.tools.keytool.Main"/> <!-- java 8 --> + </condition> + + <property name="server.alias" value="serveralias"/> + <property name="server.keypass" value="serverPassword"/> + <property name="server.keystore" value="${basedir}/target/serverStore.jks"/> + <property name="server.storepass" value="keystorePass"/> + <property name="server.dname" value="'cn=serveralias'"/> + <property name="server.file" value="${basedir}/target/serverKey.rsa"/> + + <property name="client.alias" value="clientalias"/> + <property name="client.keypass" value="clientPassword"/> + <property name="client.keystore" value="${basedir}/target/test-classes/META-INF/clientStore.jks"/> + <property name="client.storepass" value="keystorePass"/> + <property name="client.dname" value="'cn=clientalias'"/> + <property name="client.file" value="${basedir}/target/test-classes/META-INF/clientKey.rsa"/> + + <property name="keyalg" value="RSA"/> + + <!-- now create our JDK specific targets --> + <target name="do.ibm.jdk" if="is.ibm.jdk"> + <echo message="*** Running on an IBM JDK ***"/> + <echo message="generate server keys"/> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-genkey"/> + <arg line="-alias ${server.alias}"/> + <arg line="-keypass ${server.keypass}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + <arg line="-dname ${server.dname}"/> + <arg line="-keyalg ${keyalg}"/> + </java> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-selfcert"/> + <arg line="-alias ${server.alias}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + <arg line="-keypass ${server.keypass}"/> + </java> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-export"/> + <arg line="-alias ${server.alias}"/> + <arg line="-file ${server.file}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + </java> + + <echo message="generate client keys"/> + + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-genkey"/> + <arg line="-alias ${client.alias}"/> + <arg line="-keypass ${client.keypass}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + <arg line="-dname ${client.dname}"/> + <arg line="-keyalg ${keyalg}"/> + </java> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-selfcert"/> + <arg line="-alias ${client.alias}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + <arg line="-keypass ${client.keypass}"/> + </java> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-export"/> + <arg line="-alias ${client.alias}"/> + <arg line="-file ${client.file}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + </java> + + <echo message="import client/server public keys in client/server keystores"/> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-import"/> + <arg line="-alias ${server.alias}"/> + <arg line="-file ${server.file}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + <arg line="-noprompt"/> + </java> + <java classname="com.ibm.crypto.tools.KeyTool" fork="true"> + <arg line="-import"/> + <arg line="-alias ${client.alias}"/> + <arg line="-file ${client.file}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + <arg line="-noprompt"/> + </java> + </target> + + <target name="do.sun.jdk" if="is.sun.jdk"> + <echo message="*** Running on a Sun JDK ***"/> + <echo message="generate server keys"/> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-genkey"/> + <arg line="-alias ${server.alias}"/> + <arg line="-keypass ${server.keypass}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + <arg line="-dname ${server.dname}"/> + <arg line="-keyalg ${keyalg}"/> + </java> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-selfcert"/> + <arg line="-alias ${server.alias}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + <arg line="-keypass ${server.keypass}"/> + </java> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-export"/> + <arg line="-alias ${server.alias}"/> + <arg line="-file ${server.file}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + </java> + + <echo message="generate client keys"/> + + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-genkey"/> + <arg line="-alias ${client.alias}"/> + <arg line="-keypass ${client.keypass}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + <arg line="-dname ${client.dname}"/> + <arg line="-keyalg ${keyalg}"/> + </java> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-selfcert"/> + <arg line="-alias ${client.alias}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + <arg line="-keypass ${client.keypass}"/> + </java> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-export"/> + <arg line="-alias ${client.alias}"/> + <arg line="-file ${client.file}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + </java> + + <echo message="import client/server public keys in client/server keystores"/> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-import"/> + <arg line="-alias ${server.alias}"/> + <arg line="-file ${server.file}"/> + <arg line="-keystore ${client.keystore}"/> + <arg line="-storepass ${client.storepass}"/> + <arg line="-noprompt"/> + </java> + <java classname="${is.sun.jdk}" fork="true"> + <arg line="-import"/> + <arg line="-alias ${client.alias}"/> + <arg line="-file ${client.file}"/> + <arg line="-keystore ${server.keystore}"/> + <arg line="-storepass ${server.storepass}"/> + <arg line="-noprompt"/> + </java> + </target> + + <!-- run everything from our main target --> + <!-- the other targets will only be run when their properties are true --> + <target name="run" depends="do.sun.jdk, do.ibm.jdk"> + <echo message="Running JDK specific keystore creation target"/> + </target> + +</project> + diff --git a/examples/webservice-ssl-client-cert/keys/generateKeyPair.bat b/examples/webservice-ssl-client-cert/keys/generateKeyPair.bat new file mode 100644 index 0000000..48670b2 --- /dev/null +++ b/examples/webservice-ssl-client-cert/keys/generateKeyPair.bat @@ -0,0 +1,31 @@ +@echo off +REM================================================ +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. +REM _______________________________________________ +REM $Rev: 636963 $ $Date: 2008-03-13 19:40:08 -0700 (Thu, 13 Mar 2008) $ +REM================================================ + +rem @echo off +echo alias %1 +echo keypass %2 +echo keystoreName %3 +echo KeyStorePass %4 +echo keyName %5 + +echo keyName %5 +keytool -genkey -alias %1 -keypass %2 -keystore "%3" -storepass %4 -dname "cn=%1" -keyalg RSA +keytool -selfcert -alias %1 -keystore "%3" -storepass %4 -keypass %2 +keytool -export -alias %1 -file %5 -keystore "%3" -storepass %4 diff --git a/examples/webservice-ssl-client-cert/keys/generateServerKey.bat b/examples/webservice-ssl-client-cert/keys/generateServerKey.bat new file mode 100644 index 0000000..8be96bb --- /dev/null +++ b/examples/webservice-ssl-client-cert/keys/generateServerKey.bat @@ -0,0 +1,24 @@ +@echo off +REM================================================ +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. +REM _______________________________________________ +REM $Rev: 636963 $ $Date: 2008-03-13 19:40:08 -0700 (Thu, 13 Mar 2008) $ +REM================================================ + +call generateKeyPair.bat serveralias serverPassword serverStore.jks keystorePass serverKey.rsa +call generateKeyPair.bat clientalias clientPassword clientStore.jks keystorePass clientKey.rsa +keytool -import -alias serveralias -file serverKey.rsa -keystore clientStore.jks -storepass keystorePass -noprompt +keytool -import -alias clientalias -file clientKey.rsa -keystore serverStore.jks -storepass keystorePass -noprompt diff --git a/examples/webservice-ssl-client-cert/pom.xml b/examples/webservice-ssl-client-cert/pom.xml new file mode 100644 index 0000000..3f81ec6 --- /dev/null +++ b/examples/webservice-ssl-client-cert/pom.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. +--> + +<!-- $Rev: 684173 $ $Date: 2008-08-08 20:13:24 -0700 (Fri, 08 Aug 2008) $ --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.superbiz</groupId> + <artifactId>webservice-ssl-client-cert</artifactId> + <packaging>jar</packaging> + <version>8.0.0-SNAPSHOT</version> + <name>OpenEJB :: Web Examples :: EJB WebService with SSL Client Certificate</name> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <build> + <defaultGoal>install</defaultGoal> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.7</version> + <executions> + <execution> + <id>generate-keys</id> + <phase>process-test-resources</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target name="generate keys"> + <ant antfile="create-keystores.xml" target="run" /> + </target> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + <repositories> + <repository> + <id>apache-m2-snapshot</id> + <name>Apache Snapshot Repository</name> + <url>https://repository.apache.org/content/groups/snapshots</url> + </repository> + </repositories> + <dependencies> + <dependency> + <groupId>org.apache.tomee</groupId> + <artifactId>javaee-api</artifactId> + <version>8.0</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jboss.arquillian.junit</groupId> + <artifactId>arquillian-junit-container</artifactId> + <version>1.1.13.Final</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.tomee</groupId> + <artifactId>arquillian-tomee-remote</artifactId> + <version>8.0.0-SNAPSHOT</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.jboss.shrinkwrap</groupId> + <artifactId>shrinkwrap-impl-base</artifactId> + </exclusion> + </exclusions> + </dependency> + <!-- + The <scope>test</scope> guarantees that non of your runtime + code is dependent on any OpenEJB classes. + --> + <dependency> + <groupId>org.apache.tomee</groupId> + <artifactId>openejb-cxf</artifactId> + <version>8.0.0-SNAPSHOT</version> + <scope>test</scope> + </dependency> + <!-- This is required on IBM JDKs (and potentially others) because saaj-impl depends + on Sun's internal copy of Xerces. See OPENEJB-1126. --> + <dependency> + <groupId>com.sun.xml.parsers</groupId> + <artifactId>jaxp-ri</artifactId> + <version>1.4.2</version> + <scope>test</scope> + </dependency> + </dependencies> + + <!-- + This section allows you to configure where to publish libraries for sharing. + It is not required and may be deleted. For more information see: + http://maven.apache.org/plugins/maven-deploy-plugin/ + --> + <distributionManagement> + <repository> + <id>localhost</id> + <url>file://${basedir}/target/repo/</url> + </repository> + <snapshotRepository> + <id>localhost</id> + <url>file://${basedir}/target/snapshot-repo/</url> + </snapshotRepository> + </distributionManagement> + +</project> diff --git a/examples/webservice-ssl-client-cert/src/main/java/org/superbiz/calculator/CalculatorImpl.java b/examples/webservice-ssl-client-cert/src/main/java/org/superbiz/calculator/CalculatorImpl.java new file mode 100644 index 0000000..ec10543 --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/main/java/org/superbiz/calculator/CalculatorImpl.java @@ -0,0 +1,49 @@ +/** + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 javax.annotation.security.DeclareRoles; +import javax.annotation.security.RolesAllowed; +import javax.ejb.Stateless; +import javax.jws.WebService; + +/** + * This is an EJB 3 style pojo stateless session bean + * Every stateless session bean implementation must be annotated + * using the annotation @Stateless + * This EJB has a single interface: CalculatorWs a webservice interface. + */ +//START SNIPPET: code +@DeclareRoles(value = {"Administrator"}) +@Stateless +@WebService( + portName = "CalculatorPort", + serviceName = "CalculatorWsService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.calculator.CalculatorWs") +public class CalculatorImpl implements CalculatorWs { + + public int sum(int add1, int add2) { + return add1 + add2; + } + + public int multiply(int mul1, int mul2) { + return mul1 * mul2; + } + +} +//END SNIPPET: code \ No newline at end of file diff --git a/examples/webservice-ssl-client-cert/src/main/java/org/superbiz/calculator/CalculatorWs.java b/examples/webservice-ssl-client-cert/src/main/java/org/superbiz/calculator/CalculatorWs.java new file mode 100644 index 0000000..ba43aff --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/main/java/org/superbiz/calculator/CalculatorWs.java @@ -0,0 +1,35 @@ +/** + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 javax.jws.WebService; + +//END SNIPPET: code +/** + * This is an EJB 3 webservice interface + * A webservice interface must be annotated with the @Local + * annotation. + */ +//START SNIPPET: code +@WebService(targetNamespace = "http://superbiz.org/wsdl") +public interface CalculatorWs { + + int sum(int add1, int add2); + + int multiply(int mul1, int mul2); +} +//END SNIPPET: code \ No newline at end of file diff --git a/examples/webservice-ssl-client-cert/src/main/resources/META-INF/ejb-jar.xml b/examples/webservice-ssl-client-cert/src/main/resources/META-INF/ejb-jar.xml new file mode 100644 index 0000000..3c3de1c --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/main/resources/META-INF/ejb-jar.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. +--> +<ejb-jar/> \ No newline at end of file diff --git a/examples/webservice-ssl-client-cert/src/main/resources/META-INF/openejb-jar.xml b/examples/webservice-ssl-client-cert/src/main/resources/META-INF/openejb-jar.xml new file mode 100644 index 0000000..34fbdfa --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/main/resources/META-INF/openejb-jar.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. +--> +<openejb-jar xmlns="http://tomee.apache.org/xml/ns/openejb-jar-2.2"> + <enterprise-beans> + <session> + <ejb-name>CalculatorImpl</ejb-name> + <web-service-security> + <security-realm-name/> + <transport-guarantee>CONFIDENTIAL</transport-guarantee> + </web-service-security> + </session> + </enterprise-beans> +</openejb-jar> \ No newline at end of file diff --git a/examples/webservice-ssl-client-cert/src/test/conf/server.xml b/examples/webservice-ssl-client-cert/src/test/conf/server.xml new file mode 100644 index 0000000..8f10df3 --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/test/conf/server.xml @@ -0,0 +1,46 @@ +<?xml version='1.0' encoding='utf-8'?> +<!-- + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. +--> +<Server port="8005" shutdown="SHUTDOWN"> + <Listener className="org.apache.tomee.catalina.ServerListener"/> + <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/> + <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/> + <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/> + <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/> + + <Service name="Catalina"> + + <Connector port="8080" protocol="HTTP/1.1" + connectionTimeout="20000"/> + + <!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> + <Connector + protocol="org.apache.coyote.http11.Http11NioProtocol" + port="8443" maxThreads="200" + scheme="https" secure="true" SSLEnabled="true" + keystoreFile="../../../serverStore.jks" keystorePass="keystorePass" + keyAlias="serveralias" keyPass="serverPassword" + clientAuth="true" sslProtocol="TLS" + truststoreType="jks" truststorePass="keystorePass" + truststoreFile="../../../serverStore.jks"/> + + <Engine name="Catalina" defaultHost="localhost"> + <Host name="localhost" appBase="webapps" + unpackWARs="true" autoDeploy="true"/> + </Engine> + </Service> +</Server> diff --git a/examples/webservice-ssl-client-cert/src/test/java/org/superbiz/calculator/CalculatorTest.java b/examples/webservice-ssl-client-cert/src/test/java/org/superbiz/calculator/CalculatorTest.java new file mode 100644 index 0000000..1786339 --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/test/java/org/superbiz/calculator/CalculatorTest.java @@ -0,0 +1,154 @@ +/** + * 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(); + } + +} diff --git a/examples/webservice-ssl-client-cert/src/test/resources/META-INF/placeholder b/examples/webservice-ssl-client-cert/src/test/resources/META-INF/placeholder new file mode 100644 index 0000000..b1402c5 --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/test/resources/META-INF/placeholder @@ -0,0 +1,3 @@ +Do not delete this file + +We need the META-INF directory to exist because the key generation happens and creates the keys in this directory \ No newline at end of file diff --git a/examples/webservice-ssl-client-cert/src/test/resources/arquillian.xml b/examples/webservice-ssl-client-cert/src/test/resources/arquillian.xml new file mode 100644 index 0000000..7c97cba --- /dev/null +++ b/examples/webservice-ssl-client-cert/src/test/resources/arquillian.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. +--> +<arquillian xmlns="http://jboss.org/schema/arquillian" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://jboss.org/schema/arquillian + http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> + + <container qualifier="tomee" default="true"> + <configuration> + <property name="serverXml">src/test/conf/server.xml</property> + <property name="classifier">plus</property> + <!--<property name="httpsPort">-1</property>--> + <property name="httpPort">-1</property> + <property name="stopPort">-1</property> + <property name="ajpPort">-1</property> + <property name="conf">src/test/conf</property> + <property name="debug">false</property> + <property name="dir">target/test/tomee</property> + <property name="appWorkingDir">target/test/app</property> + <property name="properties"> + # arquillian adapter automatically activate ejbd for its own need, standalone instances can need customization like: + # tomee.remote.support=true + # tomee.serialization.class.whitelist = + # tomee.serialization.class.blacklist = org.codehaus.groovy.runtime.,org.apache.commons.collections.functors.,org.apache.xalan,java.lang.Process + </property> + </configuration> + </container> + +</arquillian>
