Author: ningjiang
Date: Tue Jun 4 08:19:48 2013
New Revision: 1489324
URL: http://svn.apache.org/r1489324
Log:
CXF-5042 Add SSL support on the netty-server
Added:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
Modified:
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServerEngine.java
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServletPipelineFactory.java
Modified:
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServerEngine.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServerEngine.java?rev=1489324&r1=1489323&r2=1489324&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServerEngine.java
(original)
+++
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServerEngine.java
Tue Jun 4 08:19:48 2013
@@ -19,12 +19,13 @@
package org.apache.cxf.transport.http.netty.server;
-
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
+
+import org.apache.cxf.configuration.jsse.TLSServerParameters;
import org.apache.cxf.transport.HttpUriMapper;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
@@ -53,6 +54,14 @@ public class NettyHttpServerEngine imple
private NettyHttpServletPipelineFactory servletPipeline;
private Map<String, NettyHttpContextHandler> handlerMap = new
ConcurrentHashMap<String, NettyHttpContextHandler>();
+
+ /**
+ * This field holds the TLS ServerParameters that are programatically
+ * configured. The tlsServerParamers (due to JAXB) holds the struct
+ * placed by SpringConfig.
+ */
+ private TLSServerParameters tlsServerParameters;
+
public NettyHttpServerEngine(
String host,
@@ -68,7 +77,30 @@ public class NettyHttpServerEngine imple
public void setProtocol(String protocol) {
this.protocol = protocol;
}
-
+
+
+ /**
+ * This method is used to programmatically set the TLSServerParameters.
+ * This method may only be called by the factory.
+ * @throws IOException
+ */
+ public void setTlsServerParameters(TLSServerParameters params) {
+
+ tlsServerParameters = params;
+
+ }
+
+ /**
+ * This method returns the programmatically set TLSServerParameters, not
+ * the TLSServerParametersType, which is the JAXB generated type used
+ * in SpringConfiguration.
+ * @return
+ */
+ public TLSServerParameters getTlsServerParameters() {
+ return tlsServerParameters;
+ }
+
+
protected Channel startServer() {
// TODO Configure the server.
final ServerBootstrap bootstrap = new ServerBootstrap(
@@ -76,7 +108,7 @@ public class NettyHttpServerEngine imple
.newCachedThreadPool(),
Executors.newCachedThreadPool()));
// Set up the event pipeline factory.
- servletPipeline = new NettyHttpServletPipelineFactory(handlerMap);
+ servletPipeline = new
NettyHttpServletPipelineFactory(tlsServerParameters, handlerMap);
bootstrap.setPipelineFactory(servletPipeline);
InetSocketAddress address = null;
if (host == null) {
Modified:
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServletPipelineFactory.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServletPipelineFactory.java?rev=1489324&r1=1489323&r2=1489324&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServletPipelineFactory.java
(original)
+++
cxf/trunk/rt/transports/http-netty/netty-server/src/main/java/org/apache/cxf/transport/http/netty/server/NettyHttpServletPipelineFactory.java
Tue Jun 4 08:19:48 2013
@@ -21,10 +21,18 @@ package org.apache.cxf.transport.http.ne
import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLEngine;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.jsse.TLSServerParameters;
import
org.apache.cxf.transport.http.netty.server.interceptor.ChannelInterceptor;
import
org.apache.cxf.transport.http.netty.server.interceptor.HttpSessionInterceptor;
import
org.apache.cxf.transport.http.netty.server.session.DefaultHttpSessionStore;
import org.apache.cxf.transport.http.netty.server.session.HttpSessionStore;
+import org.apache.cxf.transport.https.SSLUtils;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
@@ -37,12 +45,15 @@ import org.jboss.netty.handler.codec.htt
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.execution.ExecutionHandler;
import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
+import org.jboss.netty.handler.ssl.SslHandler;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.HashedWheelTimer;
import org.jboss.netty.util.Timer;
public class NettyHttpServletPipelineFactory implements ChannelPipelineFactory
{
-
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(NettyHttpServletPipelineFactory.class);
+
private final ChannelGroup allChannels = new DefaultChannelGroup();
private final HttpSessionWatchdog watchdog;
@@ -50,6 +61,8 @@ public class NettyHttpServletPipelineFac
private final ChannelHandler idleStateHandler;
private final Timer timer;
+
+ private final TLSServerParameters tlsServerParameters;
// TODO we may need to configure the thread pool from outside
private final ExecutionHandler executionHandler =
@@ -57,12 +70,14 @@ public class NettyHttpServletPipelineFac
private final Map<String, NettyHttpContextHandler> handlerMap;
- public NettyHttpServletPipelineFactory(Map<String,
NettyHttpContextHandler> handlerMap) {
+ public NettyHttpServletPipelineFactory(TLSServerParameters
tlsServerParameters,
+ Map<String,
NettyHttpContextHandler> handlerMap) {
this.timer = new HashedWheelTimer();
this.idleStateHandler = new IdleStateHandler(this.timer, 60, 30, 0);
this.watchdog = new HttpSessionWatchdog();
this.handlerMap = handlerMap;
+ this.tlsServerParameters = tlsServerParameters;
new Thread(watchdog).start();
}
@@ -85,7 +100,7 @@ public class NettyHttpServletPipelineFac
}
return null;
}
-
+
public void shutdown() {
this.watchdog.stopWatching();
this.timer.stop();
@@ -113,10 +128,18 @@ public class NettyHttpServletPipelineFac
return handler;
}
- protected ChannelPipeline getDefaulHttpChannelPipeline() {
+ protected ChannelPipeline getDefaulHttpChannelPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = Channels.pipeline();
+
+ SslHandler sslHandler = configureServerSSLOnDemand();
+ if (sslHandler != null) {
+ LOG.log(Level.FINE,
+ "Server SSL handler configured and added as an interceptor
against the ChannelPipeline: {}"
+ , sslHandler);
+ pipeline.addLast("ssl", sslHandler);
+ }
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
@@ -130,6 +153,15 @@ public class NettyHttpServletPipelineFac
return pipeline;
}
+ private SslHandler configureServerSSLOnDemand() throws Exception {
+ if (tlsServerParameters != null) {
+ SSLEngine sslEngine =
SSLUtils.createServerSSLEngine(tlsServerParameters);
+ return new SslHandler(sslEngine);
+ } else {
+ return null;
+ }
+ }
+
private class HttpSessionWatchdog implements Runnable {
private boolean shouldStopWatching;
Added:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java?rev=1489324&view=auto
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
(added)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
Tue Jun 4 08:19:48 2013
@@ -0,0 +1,96 @@
+/**
+ * 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.apache.cxf.transport.https;
+
+import java.security.GeneralSecurityException;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509KeyManager;
+
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.configuration.jsse.TLSParameterBase;
+import org.apache.cxf.configuration.jsse.TLSServerParameters;
+
+public final class SSLUtils {
+ private SSLUtils() {
+ //Helper class
+ }
+
+ public static SSLContext getSSLContext(TLSParameterBase parameters) throws
Exception {
+ // TODO do we need to cache the context
+ String provider = parameters.getJsseProvider();
+
+ String protocol = parameters.getSecureSocketProtocol() != null ?
parameters
+ .getSecureSocketProtocol() : "TLS";
+
+ SSLContext ctx = provider == null ? SSLContext.getInstance(protocol) :
SSLContext
+ .getInstance(protocol, provider);
+
+ if (parameters instanceof TLSClientParameters) {
+
ctx.getClientSessionContext().setSessionTimeout(((TLSClientParameters)parameters).getSslCacheTimeout());
+ }
+
+ // TODO setting on the server side
+
+ KeyManager[] keyManagers = parameters.getKeyManagers();
+ if (parameters.getCertAlias() != null) {
+ getKeyManagersWithCertAlias(parameters, keyManagers);
+ }
+ ctx.init(keyManagers, parameters.getTrustManagers(),
+ parameters.getSecureRandom());
+
+ return ctx;
+ }
+
+ protected static void getKeyManagersWithCertAlias(TLSParameterBase
tlsParameters,
+ KeyManager[] keyManagers)
+ throws GeneralSecurityException {
+ if (tlsParameters.getCertAlias() != null) {
+ for (int idx = 0; idx < keyManagers.length; idx++) {
+ if (keyManagers[idx] instanceof X509KeyManager) {
+ try {
+ keyManagers[idx] = new
AliasedX509ExtendedKeyManager(tlsParameters.getCertAlias(),
+
(X509KeyManager)keyManagers[idx]);
+ } catch (Exception e) {
+ throw new GeneralSecurityException(e);
+ }
+ }
+ }
+ }
+ }
+
+ public static SSLEngine createServerSSLEngine(TLSServerParameters
parameters) throws Exception {
+ SSLContext sslContext = getSSLContext(parameters);
+ SSLEngine serverEngine = sslContext.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+
serverEngine.setNeedClientAuth(parameters.getClientAuthentication().isRequired());
+ return serverEngine;
+ }
+
+ public static SSLEngine createClientSSLEngine(TLSClientParameters
parameters) throws Exception {
+ SSLContext sslContext = getSSLContext(parameters);
+ SSLEngine clientEngine = sslContext.createSSLEngine();
+ clientEngine.setUseClientMode(true);
+ return clientEngine;
+ }
+
+
+}