You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2020/09/06 00:21:36 UTC

[knox] branch master updated: KNOX-2412 - Add Logout Link to Home Page for Select Authentication Pr… (#372)

This is an automated email from the ASF dual-hosted git repository.

lmccay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new 235bfd4  KNOX-2412 - Add Logout Link to Home Page for Select Authentication Pr… (#372)
235bfd4 is described below

commit 235bfd4333a77871acccb127663faf22c82dad6e
Author: lmccay <lm...@apache.org>
AuthorDate: Sat Sep 5 20:21:26 2020 -0400

    KNOX-2412 - Add Logout Link to Home Page for Select Authentication Pr… (#372)
    
    * KNOX-2412 - Add Logout Link to Home Page for Select Authentication Providers
---
 gateway-release/home/conf/gateway-site.xml         |  7 ++
 gateway-release/home/conf/topologies/homepage.xml  |  6 ++
 gateway-release/pom.xml                            |  2 +-
 .../gateway/config/impl/GatewayConfigImpl.java     |  6 ++
 .../gateway/service/knoxsso/WebSSOutResource.java  |  2 +-
 .../KnoxSSOutServiceDeploymentContributor.java     |  2 +-
 gateway-service-session/pom.xml                    | 74 ++++++++++++++++++
 .../service/session/SessionInformation.java        | 34 +++++----
 .../session/SessionInformationMarshaller.java      | 89 ++++++++++++++++++++++
 .../gateway/service/session/SessionResource.java   | 65 ++++++++++++++++
 .../SessionServiceDeploymentContributor.java       | 12 +--
 .../service/session/SessionServiceMessages.java    | 31 ++------
 ...nox.gateway.deploy.ServiceDeploymentContributor | 18 +++++
 .../apache/knox/gateway/config/GatewayConfig.java  |  5 ++
 .../org/apache/knox/gateway/GatewayTestConfig.java |  5 ++
 knox-homepage-ui/home/app/app.module.ts            |  9 ++-
 knox-homepage-ui/home/app/homepage.service.ts      | 34 +++++++++
 .../session.information.component.html             | 35 +++++++++
 .../session.information.component.ts               | 80 +++++++++++++++++++
 .../app/sessionInformation/session.information.ts  | 21 +++++
 knox-homepage-ui/home/index.html                   |  1 +
 pom.xml                                            |  6 ++
 22 files changed, 493 insertions(+), 51 deletions(-)

diff --git a/gateway-release/home/conf/gateway-site.xml b/gateway-release/home/conf/gateway-site.xml
index 7ca8705..eea1879 100644
--- a/gateway-release/home/conf/gateway-site.xml
+++ b/gateway-release/home/conf/gateway-site.xml
@@ -89,6 +89,13 @@ limitations under the License.
         <description>The interval (in seconds) for polling Ambari for cluster configuration changes.</description>
     </property>
 
+    <!-- @since 1.5.0 homepage logout -->
+    <property>
+        <name>knox.homepage.logout.enabled</name>
+        <value>true</value>
+        <description>Enable/disable logout from the Knox Homepage.</description>
+    </property>
+
     <!-- Knox Admin related config -->
     <property>
         <name>gateway.knox.admin.groups</name>
diff --git a/gateway-release/home/conf/topologies/homepage.xml b/gateway-release/home/conf/topologies/homepage.xml
index 97ed15a..edf463e 100644
--- a/gateway-release/home/conf/topologies/homepage.xml
+++ b/gateway-release/home/conf/topologies/homepage.xml
@@ -54,6 +54,12 @@
       </provider>
    </gateway>
    <service>
+      <role>KNOXSSOUT</role>
+   </service>
+   <service>
+      <role>KNOX-SESSION</role>
+   </service>
+   <service>
       <role>KNOX-METADATA</role>
    </service>
    <application>
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index 4271b4c..73b6920 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -451,7 +451,7 @@
         </dependency>
         <dependency>
             <groupId>org.apache.knox</groupId>
-            <artifactId>gateway-service-metadata</artifactId>
+            <artifactId>gateway-service-session</artifactId>
         </dependency>
     </dependencies>
 </project>
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index 6fe3af2..5329320 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -261,6 +261,7 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
   private static final String KNOX_HOMEPAGE_PINNED_TOPOLOGIES =  "knox.homepage.pinned.topologies";
   private static final String KNOX_HOMEPAGE_HIDDEN_TOPOLOGIES =  "knox.homepage.hidden.topologies";
   private static final Set<String> KNOX_HOMEPAGE_HIDDEN_TOPOLOGIES_DEFAULT = new HashSet<>(Arrays.asList("admin", "manager", "knoxsso", "metadata", "homepage"));
+  private static final String KNOX_HOMEPAGE_LOGOUT_ENABLED =  "knox.homepage.logout.enabled";
 
   public GatewayConfigImpl() {
     init();
@@ -1174,4 +1175,9 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     return get(GATEWAY_SERVICE_PREFIX + service + "." + parameter, "");
   }
 
+  @Override
+  public boolean homePageLogoutEnabled() {
+    return getBoolean(KNOX_HOMEPAGE_LOGOUT_ENABLED, false);
+  }
+
 }
diff --git a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
index 1520968..623274a 100644
--- a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
+++ b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
@@ -44,7 +44,7 @@ public class WebSSOutResource {
   private static final String SSO_COOKIE_NAME = "knoxsso.cookie.name";
   private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt";
 
-  static final String RESOURCE_PATH = "/api/v1/webssout";
+  static final String RESOURCE_PATH = "knoxssout/api/v1/webssout";
 
   private String cookieName;
 
diff --git a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
index d183734..d0b9924 100644
--- a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
+++ b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
@@ -38,7 +38,7 @@ public class KnoxSSOutServiceDeploymentContributor extends JerseyServiceDeployme
 
   @Override
   protected String[] getPatterns() {
-    return new String[]{ "api/**?**" };
+    return new String[]{ "knoxssout/api/**?**" };
   }
 
 }
diff --git a/gateway-service-session/pom.xml b/gateway-service-session/pom.xml
new file mode 100644
index 0000000..15e7108
--- /dev/null
+++ b/gateway-service-session/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.knox</groupId>
+        <artifactId>gateway</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>gateway-service-session</artifactId>
+    <name>gateway-service-session</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-i18n</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-provider-jersey</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-util-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>eclipselink</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.hk2.external</groupId>
+            <artifactId>javax.inject</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
similarity index 59%
copy from gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
copy to gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
index d183734..74b57f5 100644
--- a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
+++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
@@ -15,30 +15,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.knox.gateway.service.knoxsso.deploy;
+package org.apache.knox.gateway.service.session;
 
-import org.apache.knox.gateway.jersey.JerseyServiceDeploymentContributorBase;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
 
-public class KnoxSSOutServiceDeploymentContributor extends JerseyServiceDeploymentContributorBase {
+@XmlRootElement(name = "sessioninfo")
+public class SessionInformation {
+  @XmlElement
+  private String user;
 
-  @Override
-  public String getRole() {
-    return "KNOXSSOUT";
-  }
+  @XmlElement
+  private String logoutUrl;
 
-  @Override
-  public String getName() {
-    return "KnoxSSOutService";
+  public String getUser() {
+    return user;
   }
 
-  @Override
-  protected String[] getPackages() {
-    return new String[]{ "org.apache.knox.gateway.service.knoxsso" };
+  public void setUser(String user) {
+    this.user = user;
   }
 
-  @Override
-  protected String[] getPatterns() {
-    return new String[]{ "api/**?**" };
+  public String getLogoutUrl() {
+    return logoutUrl;
   }
 
+  public void setLogoutUrl(String logoutUrl) {
+    this.logoutUrl = logoutUrl;
+  }
 }
diff --git a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java
new file mode 100644
index 0000000..dde75c0
--- /dev/null
+++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java
@@ -0,0 +1,89 @@
+/*
+ * 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.knox.gateway.service.session;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.eclipse.persistence.jaxb.JAXBContextFactory;
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+
+@Provider
+@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+public class SessionInformationMarshaller implements MessageBodyWriter<SessionInformation>{
+  private static Marshaller xmlMarshaller;
+  private static Marshaller jsonMarshaller;
+
+  @Override
+  public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+    return SessionInformation.class == type;
+  }
+
+  @Override
+  public long getSize(SessionInformation t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+    return -1;
+  }
+
+  @Override
+  public void writeTo(SessionInformation instance, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
+    try {
+      getMarshaller(mediaType).marshal(instance, entityStream);
+    } catch (JAXBException e) {
+      throw new IOException(e);
+    }
+  }
+
+  private Marshaller getMarshaller(MediaType mediaType) throws JAXBException {
+    return MediaType.APPLICATION_JSON_TYPE.getSubtype().equals(mediaType.getSubtype()) ? getJsonMarshaller() : getXmlMarshaller();
+  }
+
+  private synchronized Marshaller getXmlMarshaller() throws JAXBException {
+    if (xmlMarshaller == null) {
+      final Map<String, Object> properties = new HashMap<>(1);
+      properties.put(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_XML);
+      xmlMarshaller = JAXBContextFactory.createContext(new Class[] { SessionInformation.class }, properties).createMarshaller();
+      xmlMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+    }
+    return xmlMarshaller;
+  }
+
+  private synchronized Marshaller getJsonMarshaller() throws JAXBException {
+    if (jsonMarshaller == null) {
+      final Map<String, Object> properties = new HashMap<>(1);
+      properties.put(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
+      jsonMarshaller = JAXBContextFactory.createContext(new Class[] { SessionInformation.class }, properties).createMarshaller();
+      jsonMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+    }
+    return jsonMarshaller;
+  }
+
+}
diff --git a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java
new file mode 100644
index 0000000..2e5aa56
--- /dev/null
+++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java
@@ -0,0 +1,65 @@
+/*
+ * 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.knox.gateway.service.session;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.security.SubjectUtils;
+
+@Singleton
+@Path("session/api/v1/")
+public class SessionResource {
+  private static final SessionServiceMessages LOG = MessagesFactory.get(SessionServiceMessages.class);
+
+  @Context
+  HttpServletRequest request;
+
+  @Context
+  ServletContext context;
+
+  @GET
+  @Produces({ APPLICATION_JSON, APPLICATION_XML })
+  @Path("sessioninfo")
+  public SessionInformation getSessionInformation() {
+    final SessionInformation sessionInfo = new SessionInformation();
+    sessionInfo.setUser(SubjectUtils.getCurrentEffectivePrincipalName());
+    final GatewayConfig config = (GatewayConfig) context.getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+    if (config != null && config.homePageLogoutEnabled()) {
+      String logoutUrl = getBaseGatewayUrl(config) + "/homepage/knoxssout/api/v1/webssout";
+      LOG.homePageLogoutEnabled(logoutUrl);
+      sessionInfo.setLogoutUrl(logoutUrl);
+    }
+
+    return sessionInfo;
+  }
+
+  private String getBaseGatewayUrl(GatewayConfig config) {
+    return request.getRequestURL().substring(0, request.getRequestURL().length() - request.getRequestURI().length()) + "/" + config.getGatewayPath();
+  }
+}
diff --git a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionServiceDeploymentContributor.java
similarity index 77%
copy from gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
copy to gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionServiceDeploymentContributor.java
index d183734..370089a 100644
--- a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
+++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionServiceDeploymentContributor.java
@@ -15,30 +15,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.knox.gateway.service.knoxsso.deploy;
+package org.apache.knox.gateway.service.session;
 
 import org.apache.knox.gateway.jersey.JerseyServiceDeploymentContributorBase;
 
-public class KnoxSSOutServiceDeploymentContributor extends JerseyServiceDeploymentContributorBase {
+public class SessionServiceDeploymentContributor extends JerseyServiceDeploymentContributorBase {
 
   @Override
   public String getRole() {
-    return "KNOXSSOUT";
+    return "KNOX-SESSION";
   }
 
   @Override
   public String getName() {
-    return "KnoxSSOutService";
+    return "knox-session";
   }
 
   @Override
   protected String[] getPackages() {
-    return new String[]{ "org.apache.knox.gateway.service.knoxsso" };
+    return new String[] { "org.apache.knox.gateway.service.session" };
   }
 
   @Override
   protected String[] getPatterns() {
-    return new String[]{ "api/**?**" };
+    return new String[] { "session/api/**?**" };
   }
 
 }
diff --git a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionServiceMessages.java
similarity index 57%
copy from gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
copy to gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionServiceMessages.java
index d183734..c5eb7c8 100644
--- a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/deploy/KnoxSSOutServiceDeploymentContributor.java
+++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionServiceMessages.java
@@ -15,30 +15,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.knox.gateway.service.knoxsso.deploy;
+package org.apache.knox.gateway.service.session;
 
-import org.apache.knox.gateway.jersey.JerseyServiceDeploymentContributorBase;
+import org.apache.knox.gateway.i18n.messages.Message;
+import org.apache.knox.gateway.i18n.messages.MessageLevel;
+import org.apache.knox.gateway.i18n.messages.Messages;
 
-public class KnoxSSOutServiceDeploymentContributor extends JerseyServiceDeploymentContributorBase {
-
-  @Override
-  public String getRole() {
-    return "KNOXSSOUT";
-  }
-
-  @Override
-  public String getName() {
-    return "KnoxSSOutService";
-  }
-
-  @Override
-  protected String[] getPackages() {
-    return new String[]{ "org.apache.knox.gateway.service.knoxsso" };
-  }
-
-  @Override
-  protected String[] getPatterns() {
-    return new String[]{ "api/**?**" };
-  }
+@Messages(logger = "org.apache.knox.gateway.service.session")
+public interface SessionServiceMessages {
 
+  @Message(level = MessageLevel.INFO, text = "Homepage Logout is enabled and will use the URL: {0}")
+  void homePageLogoutEnabled(String logUrl);
 }
diff --git a/gateway-service-session/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor b/gateway-service-session/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor
new file mode 100644
index 0000000..21ec8b1
--- /dev/null
+++ b/gateway-service-session/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor
@@ -0,0 +1,18 @@
+##########################################################################
+# 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.
+##########################################################################
+org.apache.knox.gateway.service.session.SessionServiceDeploymentContributor
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index 471170f..91585e4 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -699,4 +699,9 @@ public interface GatewayConfig {
    * @return the value of the given parameter for the given service if declared; an empty String otherwise
    */
   String getServiceParameter(String service, String parameter);
+
+  /**
+   * @return the whether logout from the knox home page is enabled or not
+   */
+  boolean homePageLogoutEnabled();
 }
diff --git a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index 499fe3f..558bb29 100644
--- a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -817,4 +817,9 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
   public String getServiceParameter(String service, String parameter) {
     return "";
   }
+
+  @Override
+  public boolean homePageLogoutEnabled() {
+    return false;
+  }
 }
diff --git a/knox-homepage-ui/home/app/app.module.ts b/knox-homepage-ui/home/app/app.module.ts
index 964e84e..22dd868 100644
--- a/knox-homepage-ui/home/app/app.module.ts
+++ b/knox-homepage-ui/home/app/app.module.ts
@@ -22,6 +22,7 @@ import {BsModalModule} from 'ng2-bs3-modal/ng2-bs3-modal';
 
 import {GeneralProxyInformationComponent} from './generalProxyInformation/general.proxy.information.component';
 import {TopologyInformationsComponent} from './topologies/topology.information.component';
+import {SessionInformationComponent} from './sessionInformation/session.information.component';
 import {HomepageService} from './homepage.service';
 
 @NgModule({
@@ -32,13 +33,15 @@ import {HomepageService} from './homepage.service';
         BsModalModule
     ],
     declarations: [GeneralProxyInformationComponent,
-                   TopologyInformationsComponent
+                   TopologyInformationsComponent,
+                   SessionInformationComponent
     ],
     providers: [HomepageService
     ],
-    bootstrap: [GeneralProxyInformationComponent,
+    bootstrap: [SessionInformationComponent,
+                GeneralProxyInformationComponent,
                 TopologyInformationsComponent
     ]
 })
 export class AppModule {
-}
+}
\ No newline at end of file
diff --git a/knox-homepage-ui/home/app/homepage.service.ts b/knox-homepage-ui/home/app/homepage.service.ts
index 0613ea3..8e6b725 100644
--- a/knox-homepage-ui/home/app/homepage.service.ts
+++ b/knox-homepage-ui/home/app/homepage.service.ts
@@ -22,10 +22,12 @@ import 'rxjs/add/operator/toPromise';
 
 import {GeneralProxyInformation} from './generalProxyInformation/general.proxy.information';
 import {TopologyInformation} from './topologies/topology.information';
+import {SessionInformation} from './sessionInformation/session.information';
 
 @Injectable()
 export class HomepageService {
     apiUrl = window.location.pathname.replace(new RegExp('home/.*'), 'api/v1/metadata/');
+    sessionUrl = window.location.pathname.replace(new RegExp('home/.*'), 'session/api/v1/sessioninfo');
     generalProxyInformationUrl = this.apiUrl + 'info';
     publicCertUrl = this.apiUrl + 'publicCert?type=';
     topologiesUrl = this.apiUrl + 'topologies';
@@ -65,6 +67,38 @@ export class HomepageService {
             });
     }
 
+    getSessionInformation(): Promise<SessionInformation> {
+        let headers = new HttpHeaders();
+        headers = this.addJsonHeaders(headers);
+        return this.http.get(this.sessionUrl, { headers: headers})
+            .toPromise()
+            .then(response => response['sessioninfo'] as SessionInformation)
+            .catch((err: HttpErrorResponse) => {
+                console.debug('HomepageService --> getSessionInformation() --> ' + this.sessionUrl + '\n  error: ' + err.message);
+                if (err.status === 401) {
+                    window.location.assign(document.location.pathname);
+                } else {
+                    return this.handleError(err);
+                }
+            });
+    }
+
+    logout(logoutUrl): Promise<JSON> {
+        let headers = new HttpHeaders();
+        headers = this.addJsonHeaders(headers);
+        return this.http.get(logoutUrl, { headers: headers})
+            .toPromise()
+            .then(response => response['loggedOut'])
+            .catch((err: HttpErrorResponse) => {
+                console.debug('HomepageService --> logout() --> ' + logoutUrl + '\n  error: ' + err.message);
+                if (err.status === 401) {
+                    window.location.assign(document.location.pathname);
+                } else {
+                    return this.handleError(err);
+                }
+            });
+    }
+
     addJsonHeaders(headers: HttpHeaders): HttpHeaders {
         return this.addCsrfHeaders(headers.append('Accept', 'application/json').append('Content-Type', 'application/json'));
     }
diff --git a/knox-homepage-ui/home/app/sessionInformation/session.information.component.html b/knox-homepage-ui/home/app/sessionInformation/session.information.component.html
new file mode 100644
index 0000000..3ab7833
--- /dev/null
+++ b/knox-homepage-ui/home/app/sessionInformation/session.information.component.html
@@ -0,0 +1,35 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<div class="table-responsive">
+    <table class="table table-striped table-hover">
+       <colgroup>
+            <col width="90%">
+            <col width="5%">
+            <col width="5%">
+        </colgroup>
+        <tbody>
+            <tr>
+                <td></td>
+                <td>Welcome</td>
+                <td>{{ getUser() }}</td>
+	        </tr>
+	        <tr *ngIf="logoutSupported">
+                <td></td>
+                <td></td>
+                <td><a class="btn btn-primary" (click)="logout()">logout</a></td>
+            </tr>
+        </tbody>
+    </table>
+</div>
\ No newline at end of file
diff --git a/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts b/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts
new file mode 100644
index 0000000..8ac572c
--- /dev/null
+++ b/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+import {Component, OnInit} from '@angular/core';
+import {HomepageService} from '../homepage.service';
+import {SessionInformation} from './session.information';
+
+@Component({
+    selector: 'app-session-information',
+    templateUrl: './session.information.component.html',
+    providers: [HomepageService]
+})
+
+export class SessionInformationComponent implements OnInit {
+
+    sessionInformation: SessionInformation;
+    logoutSupported = true;
+
+    constructor(private homepageService: HomepageService) {
+        this['showSessionInformation'] = true;
+    }
+
+    getUser() {
+        if (this.sessionInformation) {
+            console.debug('SessionInformationComponent --> getUser() --> ' + this.sessionInformation.user);
+            return this.sessionInformation.user;
+        }
+        console.debug('SessionInformationComponent --> getUser() --> dr.who');
+        return 'dr.who';
+    }
+
+    getLogoutUrl() {
+        if (this.sessionInformation) {
+            console.debug('SessionInformationComponent --> getLogoutUrl() --> ' + this.sessionInformation.logoutUrl);
+            return this.sessionInformation.logoutUrl;
+        }
+        return null;
+    }
+
+    logout() {
+        // window.alert('Are you sure???');
+        console.debug('SessionInformationComponent --> attempting logout() --> ');
+        if (this.sessionInformation) {
+            if (!this.logoutSupported) {
+                window.alert('Logout for the configured is IDP not supported.\nPlease close all browser windows to logout.');
+            }
+            else {
+                this.homepageService.logout(this.getLogoutUrl())
+                                        .then(() => location.reload());
+            }
+        }
+    }
+
+    ngOnInit(): void {
+        console.debug('SessionInformationComponent --> ngOnInit() --> ');
+        this.homepageService.getSessionInformation()
+                            .then(sessionInformation => this.setSessonInformation(sessionInformation));
+        console.debug('SessionInformationComponent --> ngOnInit() --> ' + this.sessionInformation);
+    }
+
+    setSessonInformation(sessionInformation: SessionInformation) {
+        this.sessionInformation = sessionInformation;
+        if (this.getLogoutUrl() == null) {
+            this.logoutSupported = false;
+        }
+    }
+}
diff --git a/knox-homepage-ui/home/app/sessionInformation/session.information.ts b/knox-homepage-ui/home/app/sessionInformation/session.information.ts
new file mode 100644
index 0000000..183a9d4
--- /dev/null
+++ b/knox-homepage-ui/home/app/sessionInformation/session.information.ts
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+export class SessionInformation {
+    user: string;
+    logoutUrl: string;
+}
diff --git a/knox-homepage-ui/home/index.html b/knox-homepage-ui/home/index.html
index 0feb61c..cc112e2 100644
--- a/knox-homepage-ui/home/index.html
+++ b/knox-homepage-ui/home/index.html
@@ -43,6 +43,7 @@
     </div>
 
     <div class="container-fluid">
+        <app-session-information></app-session-information>
         <app-general-proxy-information></app-general-proxy-information>
         <app-topologies-information></app-topologies-information>
     </div>
diff --git a/pom.xml b/pom.xml
index 373cd87..743a896 100644
--- a/pom.xml
+++ b/pom.xml
@@ -141,6 +141,7 @@
         <module>gateway-topology-simple</module>
         <module>gateway-topology-hadoop-xml</module>
         <module>gateway-service-metadata</module>
+        <module>gateway-service-session</module>
         <module>knox-homepage-ui</module>
     </modules>
 
@@ -1194,6 +1195,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.knox</groupId>
+                <artifactId>gateway-service-session</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.knox</groupId>
                 <artifactId>knox-homepage-ui</artifactId>
                 <version>${project.version}</version>
             </dependency>