geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jinmeil...@apache.org
Subject incubator-geode git commit: GEODE-17: Integrated Security Related Changes for Pulse and Refactor interface
Date Thu, 17 Mar 2016 22:10:49 GMT
Repository: incubator-geode
Updated Branches:
  refs/heads/feature/GEODE-17-2 d4ef0a247 -> 386ace7c8


GEODE-17: Integrated Security Related Changes for Pulse and Refactor interface


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/386ace7c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/386ace7c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/386ace7c

Branch: refs/heads/feature/GEODE-17-2
Commit: 386ace7c8936d3e02d0e11cb0849cf9829608674
Parents: d4ef0a2
Author: Jinmei Liao <jiliao@pivotal.io>
Authored: Thu Mar 17 15:09:22 2016 -0700
Committer: Jinmei Liao <jiliao@pivotal.io>
Committed: Thu Mar 17 15:10:24 2016 -0700

----------------------------------------------------------------------
 .../management/internal/ManagementAgent.java    |  10 +-
 .../security/ManagementInterceptor.java         |  20 +--
 .../gemfire/security/AccessControl.java         |   8 +-
 .../gemfire/security/Authenticator.java         |  19 ++-
 .../tools/pulse/internal/PulseAppListener.java  |  70 ++++++--
 .../internal/controllers/PulseController.java   |  13 +-
 .../tools/pulse/internal/data/Cluster.java      |   9 +
 .../pulse/internal/data/JMXDataUpdater.java     | 168 ++++++++++---------
 .../pulse/internal/data/PulseConstants.java     |  17 ++
 .../tools/pulse/internal/data/Repository.java   |  19 ++-
 .../security/GemFireAuthentication.java         | 156 +++++++++++++++++
 .../security/GemFireAuthenticationProvider.java |  85 ++++++++++
 .../pulse/internal/security/LogoutHandler.java  |  55 ++++++
 geode-pulse/src/main/resources/pulse.properties |  12 +-
 .../src/main/webapp/WEB-INF/spring-security.xml |  59 ++++---
 .../gemfire/tools/pulse/tests/PulseTest.java    |   2 +
 .../gemfire/tools/pulse/tests/Server.java       |  39 ++++-
 17 files changed, 608 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java
index 8075938..a36da80 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java
@@ -16,6 +16,7 @@
  */
 package com.gemstone.gemfire.management.internal;
 
+import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 import com.gemstone.gemfire.distributed.internal.DistributionManager;
@@ -191,6 +192,10 @@ public class ManagementAgent {
         if (logger.isDebugEnabled()) {
           logger.debug(message);
         }
+
+        if (isCustomAuthorizer()){
+          System.setProperty("spring.profiles.active", "pulse.authentication.gemfire");
+        }
       }
 
       // Find developer REST WAR file
@@ -385,8 +390,9 @@ public class ManagementAgent {
     final HashMap<String, Object> env = new HashMap<String, Object>();
 
     ManagementInterceptor securityInterceptor = null;
+    Cache cache = CacheFactory.getAnyInstance();
     if (isCustomAuthenticator()) {
-      securityInterceptor = new ManagementInterceptor((GemFireCacheImpl)CacheFactory.getAnyInstance());
+      securityInterceptor = new ManagementInterceptor(cache.getDistributedSystem().getSecurityProperties());
       env.put(JMXConnectorServer.AUTHENTICATOR, securityInterceptor);
     }
     else {
@@ -462,7 +468,7 @@ public class ManagementAgent {
 
     if (isCustomAuthorizer()) {
       if(securityInterceptor==null){
-        securityInterceptor = new ManagementInterceptor((GemFireCacheImpl)CacheFactory.getAnyInstance());
+        securityInterceptor = new ManagementInterceptor(cache.getDistributedSystem().getSecurityProperties());
       }
       MBeanServerWrapper mBeanServerWrapper = new MBeanServerWrapper(securityInterceptor);
       cs.setMBeanServerForwarder(mBeanServerWrapper);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/ManagementInterceptor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/ManagementInterceptor.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/ManagementInterceptor.java
index 0a736a9..446ec10 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/ManagementInterceptor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/ManagementInterceptor.java
@@ -17,8 +17,6 @@
 package com.gemstone.gemfire.management.internal.security;
 
 import com.gemstone.gemfire.GemFireConfigException;
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.distributed.DistributedSystem;
 import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 import com.gemstone.gemfire.internal.ClassLoadUtil;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
@@ -67,17 +65,16 @@ public class ManagementInterceptor implements JMXAuthenticator{
 	public static final String OBJECT_NAME_ACCESSCONTROL = "GemFire:service=AccessControl,type=Distributed";
 
 	private static final Logger logger = LogManager.getLogger(ManagementInterceptor.class);
-  private Cache cache;
+//  private Cache cache;
   private String authzFactoryName;
   private String postAuthzFactoryName;
   private String authenticatorFactoryName;
   private ConcurrentMap<Principal, AccessControl> cachedAuthZCallback;
   private ConcurrentMap<Principal, AccessControl> cachedPostAuthZCallback;
+  private Properties sysProps = null;
 
-  public ManagementInterceptor(Cache gemFireCacheImpl) {
-    this.cache = gemFireCacheImpl;
-    DistributedSystem system = cache.getDistributedSystem();
-    Properties sysProps = system.getProperties();
+  public ManagementInterceptor(Properties sysProps) {
+    this.sysProps = sysProps;
     this.authzFactoryName = sysProps.getProperty(DistributionConfig.SECURITY_CLIENT_ACCESSOR_NAME);
     this.postAuthzFactoryName = sysProps.getProperty(DistributionConfig.SECURITY_CLIENT_ACCESSOR_PP_NAME);
     this.authenticatorFactoryName = sysProps.getProperty(DistributionConfig.SECURITY_CLIENT_AUTHENTICATOR_NAME);
@@ -138,8 +135,7 @@ public class ManagementInterceptor implements JMXAuthenticator{
     }
 
     try {
-      Principal principal = getAuthenticator(cache.getDistributedSystem().getSecurityProperties()).authenticate(pr,
-          cache.getDistributedSystem().getDistributedMember());
+      Principal principal = getAuthenticator(sysProps).authenticate(pr);
       return new Subject(true, Collections.singleton(new JMXPrincipal(principal.getName())), Collections.EMPTY_SET,
 			    Collections.EMPTY_SET);
     } catch (AuthenticationFailedException e) {
@@ -187,7 +183,7 @@ public class ManagementInterceptor implements JMXAuthenticator{
 			try {
           Method authzMethod = ClassLoadUtil.methodFromName(authzFactoryName);
           AccessControl authzCallback = (AccessControl) authzMethod.invoke(null, (Object[]) null);
-          authzCallback.init(principal, null, cache);
+          authzCallback.init(principal, null);
           cachedAuthZCallback.put(principal, authzCallback);
           return authzCallback;
         } catch (Exception ex) {
@@ -202,7 +198,7 @@ public class ManagementInterceptor implements JMXAuthenticator{
 		try {
           Method authzMethod = ClassLoadUtil.methodFromName(postAuthzFactoryName);
           AccessControl postAuthzCallback = (AccessControl) authzMethod.invoke(null, (Object[]) null);
-          postAuthzCallback.init(principal, null, cache);
+          postAuthzCallback.init(principal, null);
           cachedPostAuthZCallback.put(principal, postAuthzCallback);
           return postAuthzCallback;
         } catch (Exception ex) {
@@ -227,7 +223,7 @@ public class ManagementInterceptor implements JMXAuthenticator{
       throw new AuthenticationFailedException(
           LocalizedStrings.HandShake_AUTHENTICATOR_INSTANCE_COULD_NOT_BE_OBTAINED.toLocalizedString());
 		}
-    auth.init(gfSecurityProperties, this.cache.getLogger(), this.cache.getSecurityLogger());
+    auth.init(gfSecurityProperties);
     return auth;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-core/src/main/java/com/gemstone/gemfire/security/AccessControl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/AccessControl.java b/geode-core/src/main/java/com/gemstone/gemfire/security/AccessControl.java
index 214d8f0..349ba76 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/security/AccessControl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/AccessControl.java
@@ -17,12 +17,14 @@
 
 package com.gemstone.gemfire.security;
 
-import java.security.Principal;
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.CacheCallback;
+import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.cache.operations.OperationContext;
 import com.gemstone.gemfire.distributed.DistributedMember;
 
+import java.security.Principal;
+
 /**
  * Specifies the interface to authorize operations at the cache or region level
  * for clients or servers. Implementations should register name of the static
@@ -68,6 +70,10 @@ public interface AccessControl extends CacheCallback {
   public void init(Principal principal, DistributedMember remoteMember,
       Cache cache) throws NotAuthorizedException;
 
+  default public void init(Principal principal, DistributedMember remoteMember) throws NotAuthorizedException {
+    init(principal, remoteMember, CacheFactory.getAnyInstance());
+  }
+
   /**
    * Check if the given operation is allowed for the cache/region.
    * 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-core/src/main/java/com/gemstone/gemfire/security/Authenticator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/Authenticator.java b/geode-core/src/main/java/com/gemstone/gemfire/security/Authenticator.java
index dcf3e7c..4f9b6f2 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/security/Authenticator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/Authenticator.java
@@ -17,14 +17,16 @@
 
 package com.gemstone.gemfire.security;
 
-import java.util.Properties;
-import java.security.Principal;
-
 import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.CacheCallback;
+import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.distributed.DistributedMember;
 import com.gemstone.gemfire.distributed.DistributedSystem;
 
+import java.security.Principal;
+import java.util.Properties;
+
 /**
  * Specifies the mechanism to verify credentials for a client or peer.
  * Implementations should register name of the static creation function as the
@@ -63,6 +65,11 @@ public interface Authenticator extends CacheCallback {
   public void init(Properties securityProps, LogWriter systemLogger,
       LogWriter securityLogger) throws AuthenticationFailedException;
 
+  default public void init(Properties securityProps)  throws AuthenticationFailedException{
+    Cache cache = CacheFactory.getAnyInstance();
+    init(securityProps, cache.getLogger(), cache.getSecurityLogger());
+  }
+
   /**
    * Verify the credentials provided in the properties for the client/peer as
    * specified in member ID and returns the principal associated with the
@@ -84,4 +91,10 @@ public interface Authenticator extends CacheCallback {
   public Principal authenticate(Properties props, DistributedMember member)
       throws AuthenticationFailedException;
 
+  default public Principal authenticate(Properties props)
+      throws AuthenticationFailedException{
+    DistributedMember member = CacheFactory.getAnyInstance().getDistributedSystem().getDistributedMember();
+    return authenticate(props, member);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/PulseAppListener.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/PulseAppListener.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/PulseAppListener.java
index 784caed..1732005 100644
--- a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/PulseAppListener.java
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/PulseAppListener.java
@@ -19,6 +19,17 @@
 
 package com.vmware.gemfire.tools.pulse.internal;
 
+import com.vmware.gemfire.tools.pulse.internal.controllers.PulseController;
+import com.vmware.gemfire.tools.pulse.internal.data.PulseConfig;
+import com.vmware.gemfire.tools.pulse.internal.data.PulseConstants;
+import com.vmware.gemfire.tools.pulse.internal.data.Repository;
+import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
+import com.vmware.gemfire.tools.pulse.internal.util.StringUtils;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
@@ -30,22 +41,12 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.ResourceBundle;
 import java.util.Set;
-import java.util.Map.Entry;
 import java.util.logging.Level;
 
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import com.vmware.gemfire.tools.pulse.internal.controllers.PulseController;
-import com.vmware.gemfire.tools.pulse.internal.data.PulseConfig;
-import com.vmware.gemfire.tools.pulse.internal.data.PulseConstants;
-import com.vmware.gemfire.tools.pulse.internal.data.Repository;
-import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
-import com.vmware.gemfire.tools.pulse.internal.util.StringUtils;
-
 /**
  * This class is used for checking the application running mode i.e. Embedded or
  * not
@@ -74,6 +75,11 @@ public class PulseAppListener implements ServletContextListener {
   
   private boolean sysPulseUseSSLLocator;
   private boolean sysPulseUseSSLManager;
+  
+  //This property determines if pulse webApp login is authenticated against
+  //GemFire integrated security or custom spring-security config provided 
+  //in pulse-authentication-custom.xml 
+  private boolean useGemFireCredentials;
 
   @Override
   public void contextDestroyed(ServletContextEvent event) {
@@ -90,7 +96,7 @@ public class PulseAppListener implements ServletContextListener {
 
   @Override
   public void contextInitialized(ServletContextEvent event) {
-
+    
     messagesToBeLogged = messagesToBeLogged
         .concat(formatLogString(resourceBundle
             .getString("LOG_MSG_CONTEXT_INITIALIZED")));
@@ -189,10 +195,11 @@ public class PulseAppListener implements ServletContextListener {
       loadJMXUserDetails();
       // Load locator and/or manager details
       loadLocatorManagerDetails();
-
+       
+      useGemFireCredentials = areWeUsingGemFireSecurityProfile(event); 
     }
-
-    // Set user details in repository
+    
+    // Set user details in repository    
     repository.setJmxUserName(jmxUserName);
     repository.setJmxUserPassword(jmxUserPassword);
 
@@ -205,7 +212,40 @@ public class PulseAppListener implements ServletContextListener {
     initializeSSL();
     repository.setUseSSLLocator(sysPulseUseSSLLocator);
     repository.setUseSSLManager(sysPulseUseSSLManager);
+    
+    repository.setUseGemFireCredentials(useGemFireCredentials);
+
+  }
 
+  /**
+   * Return true if pulse is configure to authenticate using gemfire
+   * integrated security
+   * 
+   * @param event
+   * @return
+   */
+  private boolean areWeUsingGemFireSecurityProfile(ServletContextEvent event) {
+    String profile = null;
+    WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
+    if (ctx.getEnvironment() != null) {
+      String[] profiles = ctx.getEnvironment().getActiveProfiles();
+      if (profiles != null && profiles.length > 0) {
+        StringBuilder sb = new StringBuilder();
+        for (String p : profiles)
+          sb.append(p).append(",");
+        LOGGER.info("#SpringProfilesConfigured : " + sb.toString());
+        profile = ctx.getEnvironment().getActiveProfiles()[0];
+        LOGGER.info("#First Profile : " + profile);
+      } else {
+        LOGGER.info("No SpringProfileConfigured using default spring profile");
+        return false;
+      }
+    }
+    if (PulseConstants.APPLICATION_PROPERTY_PULSE_SEC_PROFILE_GEMFIRE.equals(profile)) {
+      LOGGER.info("Using gemfire integrated security profile");
+      return true;
+    }      
+    return false;
   }
 
   // Function to load pulse version details from properties file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/controllers/PulseController.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/controllers/PulseController.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/controllers/PulseController.java
index 22be468..957340d 100644
--- a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/controllers/PulseController.java
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/controllers/PulseController.java
@@ -40,7 +40,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Iterator;
@@ -148,17 +147,25 @@ public class PulseController {
     return null != request.getUserPrincipal();
   }
 
+  /* Not used replaced by SpringSecurity Logout tag with LogoutHandler
   @RequestMapping(value = "/clusterLogout", method = RequestMethod.GET)
   public void clusterLogout(HttpServletRequest request,
       HttpServletResponse response) throws IOException {
+    PulseLogWriter LOGGER = PulseLogWriter.getLogger();   
+    LOGGER.info("Inside #clusterLogout...");    
+    if(Repository.get().isUseGemFireCredentials()) {      
+      GemFireAuthentication authentication = (GemFireAuthentication) SecurityContextHolder.getContext()
+          .getAuthentication();
+      authentication.getJmxc().close();
+      LOGGER.info("Closing GemFireAuthentication JMX Connection...");
+    }
     HttpSession session = request.getSession(false);
     if (session != null) {
-
       // End session and redirect
       session.invalidate();
     }
     response.sendRedirect("../Login.html");
-  }
+  }*/
 
   @RequestMapping(value = "/pulseVersion", method = RequestMethod.GET)
   public void pulseVersion(HttpServletRequest request,

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Cluster.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Cluster.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Cluster.java
index 5390794..ce075bd 100644
--- a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Cluster.java
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Cluster.java
@@ -54,6 +54,7 @@ import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import javax.management.remote.JMXConnector;
 /**
  * Class Cluster This class is the Data Model for the data used for the Pulse
  * Web UI.
@@ -2899,6 +2900,14 @@ public class Cluster extends Thread {
   public boolean deleteQueryById(String userId, String queryId) {
     return this.getDataBrowser().deleteQueryById(userId, queryId);
   }
+  
+  public JMXConnector connectToGemFire(String user, String password) {
+    if(this.updater instanceof JMXDataUpdater) {
+      return ((JMXDataUpdater) this.updater).getJMXConnection(user, password, false);
+    } else {
+      return null;
+    }
+  }
 
   /**
    * inner class for creating Mock Data

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/JMXDataUpdater.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/JMXDataUpdater.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/JMXDataUpdater.java
index 71dfa61..7e068ad 100644
--- a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/JMXDataUpdater.java
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/JMXDataUpdater.java
@@ -145,56 +145,91 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
 
   }
 
-  private JMXConnector getJMXConnection() {
-    JMXConnector connection = null;
-    // Reference to repository
-    Repository repository = Repository.get();
-    try {
+  private JmxManagerInfo getManagerInfoFromLocator(Repository repository) {
 
-      String jmxSerURL = "";
+    try {
+      String locatorHost = repository.getJmxHost();
+      int locatorPort = Integer.parseInt(repository.getJmxPort());
 
       if (LOGGER.infoEnabled()) {
-        LOGGER.info(resourceBundle.getString("LOG_MSG_USE_LOCATOR_VALUE") + ":"
-            + repository.getJmxUseLocator());
+        LOGGER.info(resourceBundle.getString("LOG_MSG_HOST") + " : " + locatorHost + " & "
+            + resourceBundle.getString("LOG_MSG_PORT") + " : " + locatorPort);
       }
 
-      if (repository.getJmxUseLocator()) {
+      InetAddress inetAddr = InetAddress.getByName(locatorHost);
+
+      if ((inetAddr instanceof Inet4Address) || (inetAddr instanceof Inet6Address)) {
 
-        String locatorHost = repository.getJmxHost();
-        int locatorPort = Integer.parseInt(repository.getJmxPort());
+        if (inetAddr instanceof Inet4Address) {
+          if (LOGGER.infoEnabled()) {
+            LOGGER.info(resourceBundle.getString("LOG_MSG_LOCATOR_IPV4_ADDRESS") + " - " + inetAddr.toString());
+          }
+        } else {
+          if (LOGGER.infoEnabled()) {
+            LOGGER.info(resourceBundle.getString("LOG_MSG_LOCATOR_IPV6_ADDRESS") + " - " + inetAddr.toString());
+          }
+        }
+
+        JmxManagerInfo jmxManagerInfo = JmxManagerFinder.askLocatorForJmxManager(inetAddr, locatorPort, 15000,
+            repository.isUseSSLLocator());
 
+        if (jmxManagerInfo.port == 0) {
+          if (LOGGER.infoEnabled()) {
+            LOGGER.info(resourceBundle.getString("LOG_MSG_LOCATOR_COULD_NOT_FIND_MANAGER"));
+          }
+        }
+        return jmxManagerInfo;
+      } else {
+        // Locator has Invalid locator Address
         if (LOGGER.infoEnabled()) {
-          LOGGER.info(resourceBundle.getString("LOG_MSG_HOST") + " : "
-              + locatorHost + " & " + resourceBundle.getString("LOG_MSG_PORT")
-              + " : " + locatorPort);
+          LOGGER.info(resourceBundle.getString("LOG_MSG_LOCATOR_BAD_ADDRESS"));
         }
+        cluster.setConnectionErrorMsg(resourceBundle.getString("LOG_MSG_JMX_CONNECTION_BAD_ADDRESS"));
+        // update message to display on UI
+        cluster.setConnectionErrorMsg(resourceBundle
+            .getString("LOG_MSG_JMX_CONNECTION_BAD_ADDRESS"));
+        return null;
+      }
+    } catch (IOException e) {
+      StringWriter swBuffer = new StringWriter();
+      PrintWriter prtWriter = new PrintWriter(swBuffer);
+      e.printStackTrace(prtWriter);
+      LOGGER.severe("Exception Details : " + swBuffer.toString() + "\n");
+    }
+    return null;
+  }
 
-        InetAddress inetAddr = InetAddress.getByName(locatorHost);
+  /**
+   * Default connection is Pulse which uses configured userName and password
+   * @return
+   */
+  public JMXConnector getJMXConnection() {
+    return getJMXConnection(this.userName, this.userPassword, true);
+  }
 
-        if ((inetAddr instanceof Inet4Address)
-            || (inetAddr instanceof Inet6Address)) {
+  /**
+   * Get connection for given userName and password. This is used for DataBrowser
+   * queries which has to be fired using credentials provided at pulse login page
+   *
+   * @param user jmxUser name
+   * @param password password
+   * @return
+   */
+  public JMXConnector getJMXConnection(String user, String password, final boolean registerURL) {
+    JMXConnector connection = null;
+    // Reference to repository
+    Repository repository = Repository.get();
+    try {
 
-          if (inetAddr instanceof Inet4Address) {
-            // Locator has IPv4 Address
-            if (LOGGER.infoEnabled()) {
-              LOGGER.info(resourceBundle
-                  .getString("LOG_MSG_LOCATOR_IPV4_ADDRESS")
-                  + " - "
-                  + inetAddr.toString());
-            }
-          } else {
-            // Locator has IPv6 Address
-            if (LOGGER.infoEnabled()) {
-              LOGGER.info(resourceBundle
-                  .getString("LOG_MSG_LOCATOR_IPV6_ADDRESS")
-                  + " - "
-                  + inetAddr.toString());
-            }
-          }
+      String jmxSerURL = "";
 
-          JmxManagerInfo jmxManagerInfo = JmxManagerFinder
-              .askLocatorForJmxManager(inetAddr, locatorPort, 15000,
-                  repository.isUseSSLLocator());
+      if (LOGGER.infoEnabled()) {
+        LOGGER.info(resourceBundle.getString("LOG_MSG_USE_LOCATOR_VALUE") + ":"
+            + repository.getJmxUseLocator());
+      }
+
+      if (repository.getJmxUseLocator()) {
+        JmxManagerInfo jmxManagerInfo = getManagerInfoFromLocator(repository);
 
           if (jmxManagerInfo.port == 0) {
             if (LOGGER.infoEnabled()) {
@@ -221,28 +256,6 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
             jmxSerURL = formJMXServiceURLString(jmxManagerInfo.host,
                 String.valueOf(jmxManagerInfo.port));
           }
-
-        } /*
-           * else if (inetAddr instanceof Inet6Address) { // Locator has IPv6
-           * Address if(LOGGER.infoEnabled()){
-           * LOGGER.info(resourceBundle.getString
-           * ("LOG_MSG_LOCATOR_IPV6_ADDRESS")); } // update message to display
-           * on UI cluster.setConnectionErrorMsg(resourceBundle.getString(
-           * "LOG_MSG_JMX_CONNECTION_IPv6_ADDRESS"));
-           *
-           * }
-           */else {
-          // Locator has Invalid locator Address
-          if (LOGGER.infoEnabled()) {
-            LOGGER
-                .info(resourceBundle.getString("LOG_MSG_LOCATOR_BAD_ADDRESS"));
-          }
-          // update message to display on UI
-          cluster.setConnectionErrorMsg(resourceBundle
-              .getString("LOG_MSG_JMX_CONNECTION_BAD_ADDRESS"));
-
-        }
-
       } else {
         if (LOGGER.infoEnabled()) {
           LOGGER.info(resourceBundle.getString("LOG_MSG_HOST") + " : "
@@ -254,11 +267,8 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
 
       if (StringUtils.isNotNullNotEmptyNotWhiteSpace(jmxSerURL)) {
         JMXServiceURL url = new JMXServiceURL(jmxSerURL);
-
-        // String[] creds = {"controlRole", "R&D"};
-        String[] creds = { this.userName, this.userPassword };
+        String[] creds = { user, password };
         Map<String, Object> env = new HashMap<String, Object>();
-
         env.put(JMXConnector.CREDENTIALS, creds);
 
         if (repository.isUseSSLManager()) {
@@ -266,20 +276,19 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
           env.put("com.sun.jndi.rmi.factory.socket",
               new SslRMIClientSocketFactory());
         }
-
+        LOGGER.info("Connecting to jmxURL : " + jmxSerURL);
         connection = JMXConnectorFactory.connect(url, env);
 
         // Register Pulse URL if not already present in the JMX Manager
-        registerPulseUrlToManager(connection);
+        if(registerURL)
+          registerPulseUrlToManager(connection);
       }
     } catch (Exception e) {
       if (e instanceof UnknownHostException) {
-        // update message to display on UI
         cluster.setConnectionErrorMsg(resourceBundle
             .getString("LOG_MSG_JMX_CONNECTION_UNKNOWN_HOST"));
       }
 
-      // write errors
       StringWriter swBuffer = new StringWriter();
       PrintWriter prtWriter = new PrintWriter(swBuffer);
       e.printStackTrace(prtWriter);
@@ -294,7 +303,6 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
         this.conn = null;
       }
     }
-
     return connection;
   }
 
@@ -1222,12 +1230,12 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
           if (cmd.containsKey(PulseConstants.COMPOSITE_DATA_KEY_CONNECTED)){
             client.setConnected((Boolean) cmd.get(PulseConstants.COMPOSITE_DATA_KEY_CONNECTED));
           }
-          if (cmd.containsKey(PulseConstants.COMPOSITE_DATA_KEY_CLIENTCQCOUNT)){ 
-        	client.setClientCQCount((Integer) cmd.get(PulseConstants.COMPOSITE_DATA_KEY_CLIENTCQCOUNT)); 
-          } 
-          if (cmd.containsKey(PulseConstants.COMPOSITE_DATA_KEY_SUBSCRIPTIONENABLED)){ 
-            client.setSubscriptionEnabled((Boolean) cmd.get(PulseConstants.COMPOSITE_DATA_KEY_SUBSCRIPTIONENABLED)); 
-          } 
+          if (cmd.containsKey(PulseConstants.COMPOSITE_DATA_KEY_CLIENTCQCOUNT)){
+        	client.setClientCQCount((Integer) cmd.get(PulseConstants.COMPOSITE_DATA_KEY_CLIENTCQCOUNT));
+          }
+          if (cmd.containsKey(PulseConstants.COMPOSITE_DATA_KEY_SUBSCRIPTIONENABLED)){
+            client.setSubscriptionEnabled((Boolean) cmd.get(PulseConstants.COMPOSITE_DATA_KEY_SUBSCRIPTIONENABLED));
+          }
           memberClientsHM.put(client.getId(), client);
         }
         existingMember.updateMemberClientsHMap(memberClientsHM);
@@ -1602,7 +1610,7 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
       LOGGER.warning(infe);
     } catch (ReflectionException re) {
       LOGGER.warning(re);
-    } 
+    }
   }
 
   private static boolean isQuoted(String value) {
@@ -2184,6 +2192,11 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
 
       Cluster.Member member = cluster.getMembersHMap().get(memberName);
 
+      //Following attributes are not present in 9.0
+      //"Members"
+      //"EmptyNodes"
+      //"SystemRegionEntryCount"
+      //"MemberCount"
       AttributeList attributeList = this.mbs.getAttributes(mbeanName,
           PulseConstants.REGION_MBEAN_ATTRIBUTES);
 
@@ -2301,7 +2314,7 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
           region.setDiskSynchronous(false);
           //LOGGER.warning("Some of the Pulse elements are not available currently. There might be a GemFire upgrade going on.");
       }
-     
+
 
       // Remove deleted regions from member's regions list
       for (Iterator<String> it = cluster.getDeletedRegions().iterator(); it
@@ -2316,7 +2329,7 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
       LOGGER.warning(infe);
     } catch (ReflectionException re) {
       LOGGER.warning(re);
-    } 
+    }
   }
 
   /**
@@ -2450,5 +2463,4 @@ public class JMXDataUpdater implements IClusterUpdater, NotificationListener {
 
     return gemfireVersion;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/PulseConstants.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/PulseConstants.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/PulseConstants.java
index c2999f8..b06d2e5 100644
--- a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/PulseConstants.java
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/PulseConstants.java
@@ -101,6 +101,9 @@ public class PulseConstants {
   public static final String APPLICATION_PROPERTY_PULSE_LOGLEVEL = "pulse.Log-Level";
   public static final String APPLICATION_PROPERTY_PULSE_LOGAPPEND = "pulse.Log-Append";
   public static final String APPLICATION_PROPERTY_PULSE_PRODUCTSUPPORT = "pulse.product";
+  public static final String APPLICATION_PROPERTY_PULSE_SEC_PROFILE_GEMFIRE = "pulse.authentication.gemfire";
+  public static final String APPLICATION_PROPERTY_PULSE_SEC_PROFILE_DEFAULT = "pulse.authentication.default";
+  public static final String APPLICATION_PROPERTY_PULSE_SPRING_PROFILE_KEY = "spring.profiles.default";
 
   // STRING FLAGS
   public static final String STRING_FLAG_TRUE = "true";
@@ -124,6 +127,7 @@ public class PulseConstants {
   public static final String OBJECT_NAME_TABLE_AGGREGATE_PATTERN = OBJECT_DOMAIN_NAME_SQLFIRE + ":service=Table,type=Aggregate,table=";
   public static final String OBJECT_NAME_REGION_ON_MEMBER_REGION = OBJECT_DOMAIN_NAME_GEMFIRE + ":service=Region,name=";
   public static final String OBJECT_NAME_REGION_ON_MEMBER_MEMBER = ",type=Member,member=";
+  public static final String OBJECT_NAME_ACCESSCONTROL_MBEAN = "GemFire:service=AccessControl,type=Distributed";
 
   public static final String MBEAN_KEY_PROPERTY_SERVICE = "service";
   public static final String MBEAN_KEY_PROPERTY_SERVICE_VALUE_REGION = "Region";
@@ -314,6 +318,11 @@ public class PulseConstants {
   public static final String PRODUCT_NAME_GEMFIRE = "gemfire"; // For GemFire
   public static final String PRODUCT_NAME_SQLFIRE = "gemfirexd"; // For SQLFire
 
+  //Following attributes are not present in 9.0
+  //"Members"
+  //"EmptyNodes"
+  //"SystemRegionEntryCount"
+  //"MemberCount"
   public static final String[] REGION_MBEAN_ATTRIBUTES = {
       MBEAN_ATTRIBUTE_MEMBERS, MBEAN_ATTRIBUTE_FULLPATH,
       MBEAN_ATTRIBUTE_DISKREADSRATE, MBEAN_ATTRIBUTE_DISKWRITESRATE,
@@ -403,6 +412,14 @@ public class PulseConstants {
 
   public static final String[] SF_TABLE_MBEAN_ATTRIBUTES = {
       MBEAN_ATTRIBUTE_ENTRYSIZE, MBEAN_ATTRIBUTE_NUMBEROFROWS };
+  
+  public static final String PULSE_ROLES[] = {
+    "PULSE_DASHBOARD", 
+    "PULSE_DATABROWSER", 
+    "PULSE_WEBGFSH", 
+    "PULSE_ADMIN_V1",
+    "PULSE_ADMIN_V2"
+  };
 
   // SSL Related attributes
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Repository.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Repository.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Repository.java
index 0dee7da..a11167e 100644
--- a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Repository.java
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/data/Repository.java
@@ -19,14 +19,14 @@
 
 package com.vmware.gemfire.tools.pulse.internal.data;
 
+import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
+
 import java.net.ConnectException;
 import java.util.HashMap;
-import java.util.Locale;
-import java.util.ResourceBundle;
-
-import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Map;
+import java.util.ResourceBundle;
 
 /**
  * A Singleton instance of the memory cache for clusters.
@@ -47,6 +47,7 @@ public class Repository {
   private Boolean isEmbeddedMode;
   private boolean useSSLLocator = false;
   private boolean useSSLManager = false;
+  private boolean useGemFireCredentials = false;
   
 
   private String pulseWebAppUrl;
@@ -212,4 +213,14 @@ public class Repository {
     return this.resourceBundle;
   }
 
+  public boolean isUseGemFireCredentials() {
+    return useGemFireCredentials;
+  }
+
+  public void setUseGemFireCredentials(boolean useGemFireCredentials) {
+    this.useGemFireCredentials = useGemFireCredentials;
+  }
+  
+  
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthentication.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthentication.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthentication.java
new file mode 100644
index 0000000..99dcc15
--- /dev/null
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthentication.java
@@ -0,0 +1,156 @@
+/*
+ * 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 com.vmware.gemfire.tools.pulse.internal.security;
+
+import com.vmware.gemfire.tools.pulse.internal.data.PulseConstants;
+import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnector;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Spring security authentication object for GemFire
+ * 
+ * To use GemFire Integrated Security Model set Spring Application Profile to pulse.authentication.gemfire
+ * 
+ * 1. Authentication : 
+ *    1.a GemFire profile creates JMX connection with given credentials at the login time. 
+ *    1.b Successful connect is considered as Successful Authentication for Pulse WebApp
+ *    
+ *    
+ * 2. Authorization :
+ *    2.a Using newly created authenticated connection AccessControlMXBean is called to get authentication
+ *      levels. See @See {@link #populateAuthorities(JMXConnector)}. This sets Spring Security Authorities
+ *    2.b DataBrowser end-points are required to be authorized against Spring Granted Authority
+ *      @See spring-security.xml
+ *    2.c When executing Data-Browser query, user-level jmx connection is used so at to put access-control
+ *      over the resources query is accessing. 
+ *      @See #com.vmware.gemfire.tools.pulse.internal.data.JMXDataUpdater#executeQuery
+ *         
+ * 3. Connection Management - Spring Security LogoutHandler closes session level connection
+ *
+ * TODO : Better model would be to maintain background connection map for Databrowser instead
+ * of each web session creating rmi connection and map user to correct entry in the connection map
+ * 
+ * @author Tushar Khairnar
+ * @since version 9.0
+ */
+public class GemFireAuthentication extends UsernamePasswordAuthenticationToken {	
+
+  private final static PulseLogWriter LOGGER = PulseLogWriter.getLogger();
+  
+	private JMXConnector jmxc=null;	
+	
+	public GemFireAuthentication(Object principal, Object credentials, Collection<GrantedAuthority> list, JMXConnector jmxc) {
+		super(principal, credentials, list);
+		this.jmxc = jmxc;
+	}
+
+	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+		
+	
+	public void closeJMXConnection(){
+		try {
+			jmxc.close();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+	
+	public MBeanServerConnection getRemoteMBeanServer() {
+		try {
+			return jmxc.getMBeanServerConnection();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+	
+	public static boolean authorize(String role){
+		try {
+			GemFireAuthentication authentication = (GemFireAuthentication) SecurityContextHolder
+					.getContext().getAuthentication();
+			MBeanServerConnection mbeanServer = authentication
+					.getRemoteMBeanServer();
+			LOGGER.fine("#GemFireAuthentication : Checking for role="+role);
+			ObjectName name = new ObjectName(PulseConstants.OBJECT_NAME_ACCESSCONTROL_MBEAN);
+			Object[] params = new Object[] {role};
+			String[] signature = new String[] {String.class.getCanonicalName()};
+			Boolean result = (Boolean)mbeanServer.invoke(name, "authorize", params, signature);
+			return result;
+		} catch (MalformedObjectNameException e) {
+			throw new RuntimeException(e);
+		} catch (InstanceNotFoundException e) {
+			throw new RuntimeException(e);
+		} catch (MBeanException e) {
+			throw new RuntimeException(e);
+		} catch (ReflectionException e) {
+			throw new RuntimeException(e);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	public static ArrayList<GrantedAuthority> populateAuthorities(JMXConnector jmxc) {
+		ObjectName name;
+		try {
+			name = new ObjectName(PulseConstants.OBJECT_NAME_ACCESSCONTROL_MBEAN);
+			MBeanServerConnection mbeanServer = jmxc.getMBeanServerConnection();			
+			ArrayList<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+			authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
+			for(String role : PulseConstants.PULSE_ROLES){
+				Object[] params = new Object[] {role};
+				String[] signature = new String[] {String.class.getCanonicalName()};
+				boolean result = (Boolean)mbeanServer.invoke(name, "authorize", params, signature);
+				if(result){
+				  //spring sec require ROLE_ prefix
+					authorities.add(new SimpleGrantedAuthority("ROLE_"+role)); 
+				}
+			}
+			return authorities;
+		} catch (MalformedObjectNameException e) {
+			throw new RuntimeException(e);
+		} catch (InstanceNotFoundException e) {
+			throw new RuntimeException(e);
+		} catch (MBeanException e) {
+			throw new RuntimeException(e);
+		} catch (ReflectionException e) {
+			throw new RuntimeException(e);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}		
+	}
+
+	public JMXConnector getJmxc() {
+		return jmxc;
+	}
+	
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthenticationProvider.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthenticationProvider.java
new file mode 100644
index 0000000..d98bba8
--- /dev/null
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/GemFireAuthenticationProvider.java
@@ -0,0 +1,85 @@
+/*
+ * 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 com.vmware.gemfire.tools.pulse.internal.security;
+
+import com.vmware.gemfire.tools.pulse.internal.data.Repository;
+import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+
+import javax.management.remote.JMXConnector;
+import java.util.Collection;
+
+/**
+ * Spring security AuthenticationProvider for GemFire. It connects to 
+ * gemfire manager using given credentials. Successful connect is treated
+ * as successful authentication and web user is authenticated
+ *
+ * @author Tushar Khairnar
+ * @since version 9.0
+ */
+public class GemFireAuthenticationProvider implements AuthenticationProvider {
+	
+  private final static PulseLogWriter LOGGER = PulseLogWriter.getLogger();	
+
+	public GemFireAuthenticationProvider(){
+		System.out.println("here");
+	}
+	
+	@Override
+	public Authentication authenticate(Authentication authentication)
+			throws AuthenticationException {
+			  
+		if (authentication instanceof GemFireAuthentication) {
+			GemFireAuthentication gemAuth = (GemFireAuthentication) authentication;
+			LOGGER.fine("GemAuthentication is connected? = "
+					+ gemAuth.getJmxc());
+			if(gemAuth.getJmxc()!=null && gemAuth.isAuthenticated())
+				return gemAuth;
+		}
+		
+		String name = authentication.getName();
+		String password = authentication.getCredentials().toString();
+
+		try {
+		  LOGGER.fine("Connecting to GemFire with user=" + name);
+		  JMXConnector jmxc = Repository.get().getCluster().connectToGemFire(name, password);
+		  if(jmxc!=null) {
+  			Collection<GrantedAuthority> list = GemFireAuthentication.populateAuthorities(jmxc);
+  			GemFireAuthentication auth = new GemFireAuthentication(
+  					authentication.getPrincipal(),
+  					authentication.getCredentials(), list, jmxc);
+  			LOGGER.fine("For user " + name + " authList="+ list);
+  			return auth;
+		  } else 
+		    throw new AuthenticationServiceException("JMX Connection unavailable");
+		} catch (Exception e) {
+		  throw new BadCredentialsException("Error connecting to GemFire JMX Server", e);			
+		}
+	}
+
+	@Override
+	public boolean supports(Class<?> authentication) {
+		return authentication.equals(UsernamePasswordAuthenticationToken.class);
+	}	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/LogoutHandler.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/LogoutHandler.java b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/LogoutHandler.java
new file mode 100644
index 0000000..a70925d
--- /dev/null
+++ b/geode-pulse/src/main/java/com/vmware/gemfire/tools/pulse/internal/security/LogoutHandler.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.vmware.gemfire.tools.pulse.internal.security;
+
+import com.vmware.gemfire.tools.pulse.internal.data.Repository;
+import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Handler is used to close jmx connection maintained at user-level
+ * @author tushark
+ *
+ */
+public class LogoutHandler extends SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler {
+
+  public LogoutHandler(String defaultTargetURL) {
+    this.setDefaultTargetUrl(defaultTargetURL);
+  }
+
+  public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+      throws IOException, ServletException {
+    PulseLogWriter LOGGER = PulseLogWriter.getLogger();
+    LOGGER.fine("Invoked #LogoutHandler ...");
+    if (Repository.get().isUseGemFireCredentials()) {
+      GemFireAuthentication gemauthentication = (GemFireAuthentication) authentication;
+      if(gemauthentication!=null) {
+        gemauthentication.getJmxc().close();
+        LOGGER.info("#LogoutHandler : Closing GemFireAuthentication JMX Connection...");
+      }
+    }
+    super.onLogoutSuccess(request, response, authentication);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/resources/pulse.properties
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/resources/pulse.properties b/geode-pulse/src/main/resources/pulse.properties
index 439e4b8..878bc68 100644
--- a/geode-pulse/src/main/resources/pulse.properties
+++ b/geode-pulse/src/main/resources/pulse.properties
@@ -21,11 +21,9 @@
 #Tue, 09 Oct 2012 16:39:00
 
 # JMX Locator/Manager Properties
-#pulse.useLocator=true
-#pulse.host=SachinK.clarice.com
-#pulse.useLocator=true
-#pulse.host=pnq-pratik.vmware.com
-#pulse.port=10334
+pulse.useLocator=false
+pulse.host=localhost
+pulse.port=1099
 
 pulse.useLocator=false
 pulse.host=localhost
@@ -35,8 +33,8 @@ pulse.port=9999
 #pulse.useSSL.manager=true
 
 # JMX User Properties
-pulse.jmxUserName=controlRole
-pulse.jmxUserPassword=R&D
+pulse.jmxUserName=admin
+pulse.jmxUserPassword=admin
 
 # Logging Configurations Properties
 pulse.Log-File-Name=PULSELOG

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/main/webapp/WEB-INF/spring-security.xml
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/webapp/WEB-INF/spring-security.xml b/geode-pulse/src/main/webapp/WEB-INF/spring-security.xml
index 85de9f1..5ff1f31 100644
--- a/geode-pulse/src/main/webapp/WEB-INF/spring-security.xml
+++ b/geode-pulse/src/main/webapp/WEB-INF/spring-security.xml
@@ -26,32 +26,41 @@
 	http://www.springframework.org/schema/context
 	http://www.springframework.org/schema/context/spring-context-3.2.xsd">
 
-	<http auto-config="true">
+	<http auto-config="true" use-expressions="true">
 
 		<!-- Can be invoked w/o auth -->
-		<intercept-url pattern="/Login.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
-		<intercept-url pattern="/pulse/pulseVersion" access="IS_AUTHENTICATED_ANONYMOUSLY" />
-		<intercept-url pattern="/pulse/authenticateUser" access="IS_AUTHENTICATED_ANONYMOUSLY" />
-		<intercept-url pattern="/pulse/pulseProductSupport" access="IS_AUTHENTICATED_ANONYMOUSLY" />
+		<intercept-url pattern="/Login.html" access="permitAll"  />
+		<intercept-url pattern="/pulse/pulseVersion" access="permitAll" />
+		<intercept-url pattern="/pulse/authenticateUser" access="permitAll" />
+		<intercept-url pattern="/pulse/pulseProductSupport" access="permitAll" />
 		<!-- Can be invoked w/o auth -->
 
+		<!-- Restricted urls -->		
+		<intercept-url pattern="/DataBrowser.html" access="hasRole('ROLE_PULSE_DASHBOARD') and hasRole('ROLE_PULSE_DATABROWSER')" />
+		<intercept-url pattern="/clusterDetail.html" access="hasRole('ROLE_PULSE_DASHBOARD')" />
+		<intercept-url pattern="/MemberDetails.html" access="hasRole('ROLE_PULSE_DASHBOARD')" />
+		<intercept-url pattern="/regionDetail.html" access="hasRole('ROLE_PULSE_DASHBOARD')" />		
+		<intercept-url pattern="/pulse/*" access="hasRole('ROLE_PULSE_DASHBOARD')" />
+		<intercept-url pattern="/clearAlerts" access="hasRole('ROLE_PULSE_DASHBOARD')" />
+		<intercept-url pattern="/acknowledgeAlert" access="hasRole('ROLE_PULSE_DASHBOARD')" />
+		<!-- /dataBrowserRegions, /dataBrowserQuery, /dataBrowserQueryHistory, /dataBrowserExport -->
+		<intercept-url pattern="/dataBrowser*" access="hasRole('ROLE_PULSE_DASHBOARD') and hasRole('ROLE_PULSE_DATABROWSER')" />
+		<intercept-url pattern="/getQueryStatisticsGridModel/*" access="hasRole('ROLE_PULSE_DASHBOARD') and hasRole('ROLE_PULSE_DATABROWSER')" />		
+		
 		<!-- Restricted urls -->
-		<!-- Hide Data Browser tab for Pulse-Cheetah Release -->
-		<!-- <intercept-url pattern="/DataBrowser.html" access="ROLE_RESTRICTED" /> -->
-		<!-- Restricted urls -->
-
-		<!-- Can be invoked only with auth -->
-		<intercept-url pattern="/*.html" access="ROLE_USER,ROLE_GEMFIRETESTING,ROLE_PULSEUSER" />
-		<intercept-url pattern="/pulse/*" access="ROLE_USER,ROLE_GEMFIRETESTING,ROLE_PULSEUSER" />
-		<!-- Can be invoked only with auth -->
-
 		<form-login login-page="/Login.html"
 			authentication-failure-handler-ref="authenticationFailureHandler"
 			default-target-url="/clusterDetail.html" />
-
-		<logout logout-url="/pulse/clusterLogout" logout-success-url="/Login.html" />
+		
+		<logout logout-url="/pulse/clusterLogout" success-handler-ref="customLogoutSuccessHandler"/>
+		
 	</http>
 
+	<beans:bean name="customLogoutSuccessHandler" 
+	class="com.vmware.gemfire.tools.pulse.internal.security.LogoutHandler">
+		<beans:constructor-arg value="/Login.html"/>		
+	</beans:bean>
+	
 	<beans:bean id="authenticationFailureHandler"
 		class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
 		<beans:property name="exceptionMappings">
@@ -63,21 +72,33 @@
 			</beans:props>
 		</beans:property>
 	</beans:bean>
+	
+	<beans:bean id="gemAuthenticationProvider" 
+		class="com.vmware.gemfire.tools.pulse.internal.security.GemFireAuthenticationProvider">
+  	</beans:bean>
 
-	<!-- Default user authentication based on in-memory user service -->
+	
+	<!-- Default user authentication -->
 	<beans:beans profile="pulse.authentication.default">
 		<authentication-manager>
 			<authentication-provider>
 				<user-service>
-					<user name="admin" password="admin" authorities="ROLE_USER" />
+					<user name="admin" password="admin" authorities="ROLE_USER,ROLE_PULSE_DASHBOARD,ROLE_PULSE_DATABROWSER" />
 				</user-service>
 			</authentication-provider>
 		</authentication-manager>
 	</beans:beans>
+	
+	<!-- Default user authentication based on gemfire integrated security -->
+	<beans:beans profile="pulse.authentication.gemfire">
+		<authentication-manager alias="authenticationManager">
+			<authentication-provider ref="gemAuthenticationProvider"/>
+		</authentication-manager>
+	</beans:beans>
 
 	<!-- Custom user authentication specified externally -->
 	<beans:beans profile="pulse.authentication.custom">
 		<beans:import resource="classpath:pulse-authentication-custom.xml" />
 	</beans:beans>
-
+   
 </beans:beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/PulseTest.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/PulseTest.java b/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/PulseTest.java
index c5ece20..d65d893 100644
--- a/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/PulseTest.java
+++ b/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/PulseTest.java
@@ -137,6 +137,8 @@ public class PulseTest {
 
   @BeforeClass
   public static void setUpBeforeClass() throws Exception {
+    System.setProperty("spring.profiles.active", "pulse.authentication.gemfire");
+
     ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
     jmxPropertiesFile = classLoader.getResource("test.properties").getPath();
     path = getPulseWarPath();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/386ace7c/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/Server.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/Server.java b/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/Server.java
index 02c7e3a..d84d0df 100644
--- a/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/Server.java
+++ b/geode-pulse/src/test/java/com/vmware/gemfire/tools/pulse/tests/Server.java
@@ -18,14 +18,12 @@
  */
 package com.vmware.gemfire.tools.pulse.tests;
 
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.management.internal.security.JSONAuthorization;
+import com.gemstone.gemfire.management.internal.security.MBeanServerWrapper;
+import com.gemstone.gemfire.management.internal.security.ManagementInterceptor;
 import com.vmware.gemfire.tools.pulse.internal.data.PulseConstants;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Set;
+import org.json.JSONException;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanRegistrationException;
@@ -37,6 +35,13 @@ import javax.management.ObjectName;
 import javax.management.remote.JMXConnectorServer;
 import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Properties;
+import java.util.Set;
 
 public class Server {
   private static final String DEFAULT_HOST = "127.0.0.1"; //"localhost"
@@ -46,8 +51,20 @@ public class Server {
   private final JMXConnectorServer cs;
   private String propFile = null;
 
-  public Server(int port, String properties) throws IOException {
+  public Server(int port, String properties, boolean secure) throws IOException, JSONException {
+    Properties props = new Properties();
+    props.put(DistributionConfig.SECURITY_CLIENT_AUTHENTICATOR_NAME, JSONAuthorization.class.getName() + ".create");
+    props.put(DistributionConfig.SECURITY_CLIENT_ACCESSOR_NAME, JSONAuthorization.class.getName() + ".create");
+    JSONAuthorization.setUpWithJsonFile("cacheServer.json");
+    ManagementInterceptor interceptor = new ManagementInterceptor(props);
+    MBeanServerWrapper wrapper = new MBeanServerWrapper(interceptor);
+
+    if(secure){
+      //System.setProperty(JMXConnectorServer.AUTHENTICATOR, interceptor);
+    }
+
     try {
+
       java.rmi.registry.LocateRegistry.createRegistry(port);
       System.out.println("RMI registry ready.");
     } catch (Exception e) {
@@ -60,6 +77,10 @@ public class Server {
     url = new JMXServiceURL(formJMXServiceURLString(DEFAULT_HOST, "" + port));
     cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
 
+    if(secure) {
+      cs.setMBeanServerForwarder(wrapper);
+    }
+
     cs.start();
 
     loadMBeans();
@@ -242,7 +263,7 @@ public class Server {
       throws MalformedObjectNameException {
     Server s = null;
     try {
-      s = new Server(port, properties);
+      s = new Server(port, properties, true);
     } catch (Exception e) {
       e.printStackTrace();
       return null;


Mime
View raw message