HTTPS is a communications protocol for secure all communication over a computer network, with especially wide deployment on the Internet. The main purpose of HTTPS is to provide authentication of web application.
It uses following two secure protocol layer
- SSL (Secure Sockets Layer)
- TLS (Transport Layer Security)
An asymmetric system uses two 'keys' to encrypt communications, a 'public' key and a 'private' key. Anything encrypted with the public key can only be decrypted by the private key and vice-versa. more details can be found at HTTPS .
In this blog instruction we will discuss how to enable transport layer security for web application using cxf embedded jetty.We already implemented sample web application using cxf embedded jetty Webservice with cxf using embedded Jetty . This time we will just secure this application by changing configuration.
For example purpose we used following command to prepare required Keystore , Truststore and Certificates. It is not required to use example files user always have option to use their own keystore , truststore and certificates.
keytool -v -genkey -alias KServer -keyalg RSA -keystore kblogger.jks -dname "cn=localhost, ou=KBLOG, o=blogger, c=IN" -storepass blogger -keypass blogger -validity 360 keytool -list -v -keystore kblogger.jks -storepass blogger -keypass blogger keytool -export -v -alias KServer -file client.cer -keystore kblogger.jks -storepass blogger -keypass blogger -validity 360 keytool -import -v -trustcacerts -alias KServer -file client.cer -keystore truststore.jks -storepass blogger -keypass blogger -validity 360 keytool -import -v -alias kclient -file client.cer -keystore kClient.jks -storepass blogger -keypass blogger -validity 360
- Transport layer secuirty configuration(httpj:identifiedTLSServerParameters)
- Jetty engine configuration (httpj:engine)
1. Transport layer secuirty (httpj:identifiedTLSServerParameters)
Specifies a reusable set of properties for securing an HTTP server. It has a single attribute, id, that specifies a unique identifier by which the property set can be referred.
We will use this element to configure HTTP transport layer security.
httpj:tlsServerParameters Specifies a set of properties for configuring the security used for the specific Jetty instance.
See the TLS Configuration page for more information.
Edit a xml file name cxf-jetty-beans.xml under WEB-INF/conf and add following configuration snippets
<httpj:tlsServerParameters> <sec:keyManagers keyPassword="blogger"> <sec:keyStore type="JKS" password="blogger" file="D:\kblogger.jks" /> </sec:keyManagers> <sec:trustManagers> <sec:keyStore type="JKS" password="blogger" file="D:\truststore.jks" /> </sec:trustManagers> <sec:cipherSuitesFilter> <!-- these filters ensure that a ciphersuite with export-suitable or null encryption is used, but exclude anonymous Diffie-Hellman key change as this is vulnerable to man-in-the-middle attacks --> <sec:include>.*_EXPORT_.*</sec:include> <sec:include>.*_EXPORT1024_.*</sec:include> <sec:include>.*_WITH_DES_.*</sec:include> <sec:include>.*_WITH_AES_.*</sec:include> <sec:include>.*_WITH_NULL_.*</sec:include> <sec:exclude>.*_DH_anon_.*</sec:exclude> </sec:cipherSuitesFilter> <sec:clientAuthentication want="true" required="true" /> </httpj:tlsServerParameters>Following table explain the elements and attributes of complexType TLSServerParametersIdentifiedType that we used in above xml snippet for configuring transport layer security.
ComplexType :- TLSServerParametersIdentifiedType name space :- http://cxf.apache.org/configuration/security xsd path :- http://cxf.apache.org/schemas/configuration/security.xsd |
|||||
---|---|---|---|---|---|
Element/(a)Attribute | Type | Description | |||
(a)id | String | Unique idetifier of TLS server parameters | |||
tlsServerParameters | TLSServerParametersType | Specifies an instance of the security parameters for the Jetty instance. | |||
keyManagers | KeyManagersType | This element contains the KeyManagers specification. | |||
(a)keyPassword | String | This attribute specified the password that unlock keys within the keystore. | |||
keyStore | KeyStoreType | A KeyStoreType represents the information needed to load a collection of key and certificate material from a desired location. The "url", "file", and "resource" attributes are intended to be mutually exclusive, though this assumption is not encoded in schema. The precedence order observed by the runtime is 1) "file", 2) "resource", and 3) "url". | |||
(a)type | String | This attribute specifies the type of the keystore. It is highly correlated to the provider. Most common examples are "jks" "pkcs12". | |||
(a)password | String | This attribute specifes the integrity password for the keystore. This is not the password that unlock keys within the keystore. | |||
(a)file | String | This attribute specifies the File location of the keystore. This element should be a properly accessible file from the working directory. Only one attribute of "url", "file", or "resource" is allowed. | |||
trustManagers | TrustManagersType | This structure contains the specification of JSSE TrustManagers for a single Keystore used for trusted certificates. | |||
keyStore | KeyStoreType | ||||
cipherSuitesFilter | FiltersType | This element contains the filters of the supported CipherSuites that will be supported and used if available. | |||
include | String | Include all the possible specified ciphersuite. | |||
exclude | String | Exclude all the possible specified ciphersuite. | |||
clientAuthentication | ClientAuthentication | This element contains Client Authentication specification. | |||
(a)want | String | This Boolean attribute specifies if client authentication should be requested. Example value true or false. | |||
(a)required | String | This Boolean attribute specifies if client authentication should be required. Example value true or false. |
2. Jetty engine configuration (httpj:engine)
Referring tlsServerParameters in jetty engine configuration
<httpj:engine port="666"> <!-- Use "secureJetty" in jetty engine to activate https security --> <httpj:tlsServerParametersRef id="secureJetty" /> <!-- jetty thread pooling --> <httpj:threadingParameters minThreads="5" maxThreads="15" /> <httpj:handlers> <ref bean="defaultHandler" /> </httpj:handlers> <httpj:sessionSupport>true</httpj:sessionSupport> </httpj:engine>Finally cxf-jetty-beans.xml will looks like following
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xmlns:wsa="http://cxf.apache.org/ws/addressing" xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy" xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager" xsi:schemaLocation=" http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd http://schemas.xmlsoap.org/ws/2005/02/rm/policy http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd http://cxf.apache.org/ws/rm/manager http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <!-- import resource --> <import resource="classpath:META-INF/cxf/cxf*.xml" /> <bean id="biosocket" class="org.eclipse.jetty.server.bio.SocketConnector"> <property name="host" value="localhost" /> <property name="port" value="9003" /> </bean> <bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler" /> <!-- Cxf Bus implementation --> <cxf:bus> <!-- Cxf features implementation global --> <cxf:features> <!-- cxf logging implementation --> <cxf:logging /> </cxf:features> </cxf:bus> <!-- Jetty server configuration and implementation --> <httpj:engine-factory bus="cxf"> <!-- Transport layer secuirty --> <httpj:identifiedTLSServerParameters id="secureJetty"> <httpj:tlsServerParameters> <sec:keyManagers keyPassword="blogger"> <sec:keyStore type="JKS" password="blogger" file="D:/kblogger.jks" /> </sec:keyManagers> <sec:trustManagers> <sec:keyStore type="JKS" password="blogger" file="D:/truststore.jks" /> </sec:trustManagers> <sec:cipherSuitesFilter> <!-- these filters ensure that a ciphersuite with export-suitable or null encryption is used, but exclude anonymous Diffie-Hellman key change as this is vulnerable to man-in-the-middle attacks --> <sec:include>.*_EXPORT_.*</sec:include> <sec:include>.*_EXPORT1024_.*</sec:include> <sec:include>.*_WITH_DES_.*</sec:include> <sec:include>.*_WITH_AES_.*</sec:include> <sec:include>.*_WITH_NULL_.*</sec:include> <sec:exclude>.*_DH_anon_.*</sec:exclude> </sec:cipherSuitesFilter> <!-- want="true" --> <sec:clientAuthentication want="true" required="true" /> </httpj:tlsServerParameters> </httpj:identifiedTLSServerParameters> <!-- jetty engine configuration--> <httpj:engine port="666"> <!-- Use "secureJetty" in jetty engine to activate https security --> <httpj:tlsServerParametersRef id="secureJetty" /> <!-- jetty thread pooling --> <httpj:threadingParameters minThreads="5" maxThreads="15" /> <httpj:handlers> <ref bean="defaultHandler" /> <httpj:sessionSupport>true</httpj:sessionSupport> </httpj:handlers> </httpj:engine> </httpj:engine-factory> </beans>
Modify exsiting cxf-beans.xml WEB-INF/conf/cxf-beans.xml add following xml snippet.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:endpoint xmlns:tns="http://poc.kaustuv.com/ws/service/greetings" id="greetings" implementor="com.kaustuv.poc.ws.service.greetings.GreetingsImpl" wsdlLocation="WEB-INF/wsdl/Sample.wsdl" endpointName="tns:GreetingsPort" serviceName="tns:GreetingsService" address="https://localhost:666/Greetings"> <!-- to use the catalina default 8443 port user address="/Greetings" --> </jaxws:endpoint> </beans>
main:21:34:55,310:INFO:[STDERR]:May 14, 2015 9:34:55 PM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL INFO: Creating Service {http://poc.kaustuv.com/ws/service/greetings}GreetingsService from WSDL: WEB-INF/wsdl/Sample.wsdl main:21:34:56,283:INFO:[STDERR]:May 14, 2015 9:34:56 PM org.apache.cxf.endpoint.ServerImpl initDestination INFO: Setting the server's publish address to be https://localhost:666/Greetings main:21:34:56,456:INFO:[STDERR]:May 14, 2015 9:34:56 PM org.eclipse.jetty.server.Server doStart INFO: jetty-7.5.4.v20111024 main:21:34:56,963:INFO:[STDERR]:May 14, 2015 9:34:56 PM org.eclipse.jetty.server.AbstractConnector doStart INFO: Started CXFJettySslSocketConnector@0.0.0.0:666 STARTING main:21:34:57,179:INFO:[STDERR]:May 14, 2015 9:34:57 PM org.eclipse.jetty.server.handler.ContextHandler startContext INFO: started o.e.j.s.h.ContextHandler{,null} main:21:34:57,189:INFO :[ContextLoader]:Root WebApplicationContext: initialization completed in 6443 msWSDL url : https://localhost:666/Greetings?wsdl Before accessing wsdl url user must install certificate that server side will provide. Then after we will be able to see wsdl otherwise we will get following connection close error in browser and in server console we will get following error.
WARNING: 0:0:0:0:0:0:0:1:57089 javax.net.ssl.SSLHandshakeException: null cert chain at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1421) at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535) at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214) at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186) at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469) at org.eclipse.jetty.io.nio.SslSelectChannelEndPoint.wrap(SslSelectChannelEndPoint.java:642) at org.eclipse.jetty.io.nio.SslSelectChannelEndPoint.process(SslSelectChannelEndPoint.java:309) at org.eclipse.jetty.io.nio.SslSelectChannelEndPoint.fill(SslSelectChannelEndPoint.java:398) at org.eclipse.jetty.http.HttpParser.fill(HttpParser.java:949) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:274) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:218) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:51) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:586) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:44) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533) at java.lang.Thread.run(Thread.java:745) Caused by: javax.net.ssl.SSLHandshakeException: null cert chain at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:292) at sun.security.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1804) at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:222) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:969) at sun.security.ssl.Handshaker$1.run(Handshaker.java:909) at sun.security.ssl.Handshaker$1.run(Handshaker.java:906) at java.security.AccessController.doPrivileged(Native Method) at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1359) at org.eclipse.jetty.io.nio.SslSelectChannelEndPoint.process(SslSelectChannelEndPoint.java:283)
-
Post Development testing
- References:
Embedded Jetty
CXF documents
European Union laws require you to give European Union visitors information about cookies used on your blog. In many cases, these laws also require you to obtain consent.
As a courtesy, we have added a notice on your blog to explain Google's use of certain Blogger and Google cookies, including use of Google Analytics and AdSense cookies.