inputParams)
+ throws ResourceException, TException {
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/hp/csbu/cc/middleware/ThriftClientFactory.java.txt b/src/main/java/com/hp/csbu/cc/middleware/ThriftClientFactory.java.txt
new file mode 100644
index 000000000..880864978
--- /dev/null
+++ b/src/main/java/com/hp/csbu/cc/middleware/ThriftClientFactory.java.txt
@@ -0,0 +1,19 @@
+package com.hp.csbu.cc.middleware;
+
+import org.apache.commons.pool.impl.GenericObjectPool;
+
+/**
+ * A Thrift factory.
+ *
+ * @author liemmn
+ *
+ */
+public class ThriftClientFactory extends AuthClientFactory {
+
+ ThriftClientFactory(String host, int port,
+ int timeout, boolean clientAuth, String keyStore, String keyPass,
+ String trustStore, String trustPass) {
+ pool = new GenericObjectPool(new ThriftClientPoolFactory(host, port,
+ timeout, clientAuth, keyStore, keyPass, trustStore, trustPass));
+ }
+}
diff --git a/src/main/java/com/hp/csbu/cc/middleware/ThriftClientPoolFactory.java.txt b/src/main/java/com/hp/csbu/cc/middleware/ThriftClientPoolFactory.java.txt
new file mode 100644
index 000000000..5428ae469
--- /dev/null
+++ b/src/main/java/com/hp/csbu/cc/middleware/ThriftClientPoolFactory.java.txt
@@ -0,0 +1,71 @@
+package com.hp.csbu.cc.middleware;
+
+import org.apache.commons.pool.BasePoolableObjectFactory;
+import org.apache.thrift.protocol.TCompactProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TSocket;
+
+import com.hp.csbu.cc.security.cs.thrift.service.CsThriftService;
+
+/**
+ * ThriftConnection pool factory. Based on Apache Commons Pool.
+ *
+ * @author liemmn
+ *
+ */
+public class ThriftClientPoolFactory extends BasePoolableObjectFactory {
+ private static final String PROTOCOL = "TLS";
+ private static final String[] CIPHER_SUITES = new String[] {
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+ "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+ "TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
+ "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA" };
+
+ private String host;
+ private int port;
+ private int timeout;
+ private boolean clientAuth;
+ private String keyStore;
+ private String keyPass;
+ private String trustStore;
+ private String trustPass;
+
+
+ public ThriftClientPoolFactory(String host, int port, int timeout,
+ boolean clientAuth, String keyStore, String keyPass,
+ String trustStore, String trustPass) {
+ this.host = host;
+ this.port = port;
+ this.timeout = timeout;
+ this.clientAuth = clientAuth;
+ this.keyStore = keyStore;
+ this.keyPass = keyPass;
+ this.trustStore = trustStore;
+ this.trustPass = trustPass;
+ }
+
+ @Override
+ public AuthClient makeObject() {
+ TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters(
+ PROTOCOL, CIPHER_SUITES, clientAuth);
+ params.setKeyStore(keyStore, keyPass);
+ params.setTrustStore(trustStore, trustPass);
+
+ try {
+ TSocket clientSocket = TSSLTransportFactory.getClientSocket(host,
+ port, timeout, params);
+ TProtocol proto = new TCompactProtocol(clientSocket);
+ return new ThriftAuthClient(new CsThriftService.Client(proto));
+ } catch (Exception e) {
+ throw new AuthConnectionException("Failed to open socket " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void destroyObject(Object o) {
+ ((ThriftAuthClient) o).close();
+ o = null;
+ }
+}
diff --git a/src/main/java/com/hp/csbu/cc/middleware/TokenAuth.java b/src/main/java/com/hp/csbu/cc/middleware/TokenAuth.java
new file mode 100644
index 000000000..f226e0072
--- /dev/null
+++ b/src/main/java/com/hp/csbu/cc/middleware/TokenAuth.java
@@ -0,0 +1,185 @@
+package com.hp.csbu.cc.middleware;
+
+import java.io.IOException;
+import org.apache.http.client.ClientProtocolException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A token-based authentication filter. This filter uses Thrift protocol to
+ * communicate with the CS server. The token to validate is set via the header
+ * {@link #TOKEN}.
+ *
+ * A token is required to validate. However, if no token is presented, the
+ * filter will set the {@link #AUTH_IDENTITY_STATUS} request parameter to
+ * Invalid
and let any other filter downstream to decide what to
+ * do. For instance, if a downstream filter knows how to deal with signature
+ * rather than tokens, then it will go ahead and validate with signatures.
+ *
+ * Upon successful validation, all the Auth request parameters will be
+ * populated, including information such as tenant, user and user roles, and
+ * passed down to the next filter downstream.
+ *
+ * Upon unsuccessful validation, this filter will terminate the request by
+ * returning a 401 (unauthorized).
+ *
+ * @author liemmn
+ *
+ */
+public class TokenAuth implements Filter, AuthConstants {
+
+ private static final String TOKEN_NOTFOUND = "Bad Request: Token not found in the request";
+ private static final String SERVICE_IDS_PARAM = "serviceIds";
+ private static final String ENDPOINT_IDS_PARAM = "endpointIds";
+ private static final String SERVICE_CATALOG_PARAM = "includeCatalog";
+ private static final String API_VERSION_PARAM = "apiVersion";
+
+ private final Config appConfig = Config.getInstance();
+
+ private FilterConfig filterConfig;
+
+ // Thee faithful logger
+ private static final Logger logger = LoggerFactory
+ .getLogger(TokenAuth.class);
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ this.filterConfig = filterConfig;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void destroy() {
+ FilterUtils.destroyFilter();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void doFilter(ServletRequest req, ServletResponse resp,
+ FilterChain chain) throws IOException, ServletException {
+ Object auth = null;
+ int numberOfTries = 0;
+ if (!appConfig.isInitialized()) {
+ appConfig.initialize(filterConfig);
+ }
+ int retries = appConfig.getRetries();
+ long pauseTime = appConfig.getPauseTime();
+ AuthClientFactory factory = appConfig.getFactory();
+
+ // Extract credential
+ String token = ((HttpServletRequest) req).getHeader(TOKEN);
+
+ if (token == null) {
+ if (!appConfig.isDelayAuthDecision()) {
+ logger.error(HttpServletResponse.SC_UNAUTHORIZED
+ + " No token found.");
+ ((HttpServletResponse) resp).sendError(
+ HttpServletResponse.SC_UNAUTHORIZED, TOKEN_NOTFOUND);
+ return;
+ } else {
+ logger.info("No token found...Skipping");
+ }
+ } else {
+ // Retrieve from cache
+ auth = FilterUtils.getCachedToken(token);
+ if (auth == null) {
+ // Validate credential
+ AuthClient client = null;
+ do {
+ try {
+ client = factory.getClient();
+ if (appConfig.getAuthVersion().equalsIgnoreCase("v2.0")) {
+ auth = client.validateTokenForServiceEndpointV2(token, appConfig.getServiceIds(),
+ appConfig.getEndpointIds(), appConfig.isIncludeCatalog());
+ } else {
+ auth = client.validateTokenForServiceEndpointV3(token, getInputParams());
+ }
+ // Cache token
+ FilterUtils.cacheToken(token, auth);
+ // Return to connection pool for re-use
+ factory.recycle(client);
+ logger.debug("Successful Authentication");
+ break;
+ } catch (TTransportException t) {
+ if (client != null)
+ factory.discard(client);
+ if (numberOfTries < retries) {
+ FilterUtils.pause(pauseTime);
+ logger.debug("Retrying connection after "
+ + pauseTime + " seconds.");
+ numberOfTries++;
+ continue;
+
+ } else {
+ TokenExceptionHandler handler = TokenExceptionHandler
+ .valueOf("TException");
+ handler.onException(t, resp, token);
+ }
+ return;
+ } catch (ClientProtocolException c) {
+ if (client != null)
+ factory.discard(client);
+ if (numberOfTries < retries) {
+ FilterUtils.pause(pauseTime);
+ logger.debug("Retrying connection after "
+ + pauseTime + " seconds.");
+ numberOfTries++;
+ continue;
+
+ } else {
+ TokenExceptionHandler handler = TokenExceptionHandler
+ .valueOf("ClientProtocolException");
+ handler.onException(c, resp, token);
+ }
+ return;
+ }catch (Exception ex) {
+ if (client != null)
+ factory.recycle(client);
+ TokenExceptionHandler handler = ExceptionHandlerUtil
+ .lookUpTokenException(ex);
+ handler.onException(ex, resp, token);
+ return;
+ }
+ } while (numberOfTries <= retries);
+ } else {
+ // Got a cached token!
+ logger.debug("Got cached token: " + token);
+ }
+ }
+ req = FilterUtils.wrapRequest(req, auth);
+ logger.debug("TokenAuth: Forwarding down stream to next filter/servlet");
+ // Forward downstream...
+ chain.doFilter(req, resp);
+ }
+
+ private Map getInputParams() {
+ Map inputParams = new HashMap();
+ if (appConfig.getServiceIds() != null) {
+ inputParams.put(SERVICE_IDS_PARAM, appConfig.getServiceIds());
+ }
+ if (appConfig.getEndpointIds() != null) {
+ inputParams.put(ENDPOINT_IDS_PARAM, appConfig.getEndpointIds());
+ }
+ inputParams.put(SERVICE_CATALOG_PARAM, String.valueOf(appConfig.isIncludeCatalog()));
+ inputParams.put(API_VERSION_PARAM, appConfig.getAuthVersion());
+ return inputParams;
+ }
+
+
+}
diff --git a/src/main/java/com/hp/csbu/cc/middleware/TokenCache.java b/src/main/java/com/hp/csbu/cc/middleware/TokenCache.java
new file mode 100644
index 000000000..4c9c07d6e
--- /dev/null
+++ b/src/main/java/com/hp/csbu/cc/middleware/TokenCache.java
@@ -0,0 +1,22 @@
+package com.hp.csbu.cc.middleware;
+
+import org.apache.commons.collections4.map.PassiveExpiringMap;
+/**
+ * Created by johnderr on 6/9/14.
+ */
+public class TokenCache {
+ private PassiveExpiringMap map;
+
+ public TokenCache(Long timeToExpire) {
+ map = new PassiveExpiringMap<>(timeToExpire);
+ }
+
+ public V getToken(K key) {
+
+ return map.get(key);
+ }
+
+ public void put(K key, V value) {
+ map.put(key,value);
+ }
+}
diff --git a/src/main/java/com/hp/csbu/cc/middleware/TokenExceptionHandler.java b/src/main/java/com/hp/csbu/cc/middleware/TokenExceptionHandler.java
new file mode 100644
index 000000000..7f830ae3f
--- /dev/null
+++ b/src/main/java/com/hp/csbu/cc/middleware/TokenExceptionHandler.java
@@ -0,0 +1,108 @@
+package com.hp.csbu.cc.middleware;
+
+import java.io.IOException;
+import org.apache.http.client.ClientProtocolException;
+
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.thrift.TException;
+//import com.hp.csbu.cc.security.cs.thrift.service.ResourceException;
+
+public enum TokenExceptionHandler {
+
+ AuthConnectionException {
+ @Override
+ public void onException(Exception e, ServletResponse resp, String token) {
+ AuthConnectionException ae = (AuthConnectionException) e;
+ logger.error(ae.getMessage() + " " + ae);
+ try {
+ ((HttpServletResponse) resp).sendError(
+ HttpServletResponse.SC_UNAUTHORIZED,
+ ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)
+ + " " + token);
+ } catch (IOException ie) {
+ logger.debug("Error in writing the HTTP response "
+ + ie.getMessage() + " " + ie);
+ }
+ }
+ },
+ TException {
+ @Override
+ public void onException(Exception e, ServletResponse resp, String token) {
+ TException t = (TException) e;
+ logger.error("Thrift Exception " + t.getMessage() + " " + t);
+ try {
+ ((HttpServletResponse) resp).sendError(
+ HttpServletResponse.SC_UNAUTHORIZED,
+ ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)
+ + " " + token);
+ } catch (IOException ie) {
+ logger.debug("Error in writing the HTTP response "
+ + ie.getMessage() + " " + ie);
+ }
+ }
+ },
+ ClientProtocolException {
+ @Override
+ public void onException(Exception e, ServletResponse resp, String token) {
+ ClientProtocolException t = (ClientProtocolException) e;
+ logger.error("Http Client Exception " + t.getMessage() + " " + t);
+ try {
+ ((HttpServletResponse) resp).sendError(
+ HttpServletResponse.SC_UNAUTHORIZED,
+ ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)
+ + " " + token);
+ } catch (IOException ie) {
+ logger.debug("Error in writing the HTTP response "
+ + ie.getMessage() + " " + ie);
+ }
+ }
+ },
+ /*ResourceException {
+ @Override
+ public void onException(Exception e, ServletResponse resp, String token) {
+ ResourceException re = (ResourceException) e;
+ logger.error(HttpServletResponse.SC_UNAUTHORIZED + " " + token
+ + " " + re);
+ String statusText = re.getDetail();
+ if (statusText == null || statusText.isEmpty()) {
+ statusText = ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ try {
+ ((HttpServletResponse) resp).sendError(
+ HttpServletResponse.SC_UNAUTHORIZED, statusText + " "
+ + token);
+ } catch (IOException ie) {
+ logger.debug("Error in writing the HTTP response "
+ + ie.getMessage() + " " + ie);
+ }
+ }
+ },*/
+
+ AuthException {
+ @Override
+ public void onException(Exception e, ServletResponse resp, String token) {
+ AuthException ae = (AuthException) e;
+ logger.error(ae.getMessage() + " " + ae);
+ String statusText = ae.getMessage();
+ if (statusText == null || statusText.isEmpty()) {
+ statusText = ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ try {
+ ((HttpServletResponse) resp).sendError(
+ HttpServletResponse.SC_UNAUTHORIZED,
+ statusText + " " + token);
+ } catch (IOException ie) {
+ logger.debug("Error in writing the HTTP response "
+ + ie.getMessage() + " " + ie);
+ }
+ }
+ };
+
+ final Logger logger = LoggerFactory.getLogger(TokenExceptionHandler.class);
+ abstract void onException(Exception e, ServletResponse resp, String token);
+}
diff --git a/src/main/java/com/hpcloud/mon/infrastructure/servlet/PreAuthenticationFilter.java b/src/main/java/com/hpcloud/mon/infrastructure/servlet/PreAuthenticationFilter.java
index f92f4819e..6e6752e15 100644
--- a/src/main/java/com/hpcloud/mon/infrastructure/servlet/PreAuthenticationFilter.java
+++ b/src/main/java/com/hpcloud/mon/infrastructure/servlet/PreAuthenticationFilter.java
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
import com.hpcloud.mon.resource.exception.Exceptions;
import com.hpcloud.mon.resource.exception.Exceptions.FaultType;
-import com.hp.csbu.cc.middleware.ExceptionHandler.*;
+//import com.hp.csbu.cc.middleware.ExceptionHandler.*;
/**
* Authenticates requests using header information from the CsMiddleware. Provides the X-TENANT-ID