merrimanr closed pull request #1281: METRON-1895:  Add Knox SSO as an option in 
Metron
URL: https://github.com/apache/metron/pull/1281
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/dependencies_with_url.csv b/dependencies_with_url.csv
index bdc2508377..fdc88be9a0 100644
--- a/dependencies_with_url.csv
+++ b/dependencies_with_url.csv
@@ -489,3 +489,5 @@ 
org.hibernate.validator:hibernate-validator:jar:6.0.9.Final:compile,ASLv2,https:
 
com.github.palindromicity:simple-syslog-5424:jar:0.0.9:compile,ASLv2,https://github.com/palindromicity/simple-syslog-5424
 
org.elasticsearch.client:elasticsearch-rest-high-level-client:jar:5.6.2:compile,ASLv2,https://github.com/elastic/elasticsearch/blob/master/LICENSE.txt
 
org.elasticsearch.plugin:aggs-matrix-stats-client:jar:5.6.2:compile,ASLv2,https://github.com/elastic/elasticsearch/blob/master/LICENSE.txt
+com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile,ASLv2,http://stephenc.github.io/jcip-annotations/
+com.nimbusds:nimbus-jose-jwt:jar:4.41.2:compile,ASLv2,https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home
diff --git a/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec 
b/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
index 2839ffac2e..f6ad9661a4 100644
--- a/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
+++ b/metron-deployment/packaging/docker/rpm-docker/SPECS/metron.spec
@@ -424,8 +424,14 @@ This package installs the Metron Rest %{metron_home}
 %dir %{metron_home}/bin
 %dir %{metron_home}/lib
 %{metron_home}/config/rest_application.yml
+%{metron_home}/config/knox/conf/topologies/metron.xml
+%{metron_home}/config/knox/data/services/alerts/rewrite.xml
+%{metron_home}/config/knox/data/services/alerts/service.xml
+%{metron_home}/config/knox/data/services/rest/rewrite.xml
+%{metron_home}/config/knox/data/services/rest/service.xml
 %{metron_home}/bin/metron-rest.sh
 %{metron_home}/bin/pcap_to_pdml.sh
+%{metron_home}/bin/install_metron_knox.sh
 %attr(0644,root,root) %{metron_home}/lib/metron-rest-%{full_version}.jar
 
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git 
a/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js 
b/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js
index 58f7d26b41..5c1629fd9d 100644
--- a/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js
+++ b/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js
@@ -25,6 +25,11 @@ context('PCAP Tab', () => {
       url: '/api/v1/user',
       response: 'user'
     });
+    cy.route({
+        method: 'POST',
+        url: '/api/v1/logout',
+        response: []
+    });
 
     cy.route('GET', 'config', 'fixture:config.json');
     cy.route('POST', 'search', 'fixture:search.json');
diff --git a/metron-interface/metron-alerts/proxy.conf.json 
b/metron-interface/metron-alerts/proxy.conf.json
index 612bd67420..571af9af91 100644
--- a/metron-interface/metron-alerts/proxy.conf.json
+++ b/metron-interface/metron-alerts/proxy.conf.json
@@ -2,9 +2,5 @@
   "/api/v1": {
     "target": "http://node1:8082";,
     "secure": false
-  },
-  "/logout": {
-    "target": "http://node1:8082";,
-    "secure": false
   }
 }
diff --git a/metron-interface/metron-alerts/src/app/app.component.html 
b/metron-interface/metron-alerts/src/app/app.component.html
index d94a6d72d1..1e1e9bf67c 100644
--- a/metron-interface/metron-alerts/src/app/app.component.html
+++ b/metron-interface/metron-alerts/src/app/app.component.html
@@ -14,7 +14,7 @@
 <div class="container-fluid px-0" [class.notransition]="noTransition">
     <nav class="navbar" *ngIf="loggedIn">
         <a class="" href="#">
-            <img alt="" src="../assets/images/logo.png" width="135" 
height="45">
+            <img alt="" src="assets/images/logo.png" width="135" height="45">
         </a>
         <ul class="nav ml-4">
             <li class="nav-item" routerLinkActive="active">
diff --git 
a/metron-interface/metron-alerts/src/app/service/authentication.service.ts 
b/metron-interface/metron-alerts/src/app/service/authentication.service.ts
index 7739be128d..f8b58451e2 100644
--- a/metron-interface/metron-alerts/src/app/service/authentication.service.ts
+++ b/metron-interface/metron-alerts/src/app/service/authentication.service.ts
@@ -30,7 +30,7 @@ export class AuthenticationService {
   private static USER_NOT_VERIFIED = 'USER-NOT-VERIFIED';
   private currentUser: string = AuthenticationService.USER_NOT_VERIFIED;
   loginUrl = this.appConfigService.getApiRoot() + '/user';
-  logoutUrl = '/logout';
+  logoutUrl = this.appConfigService.getApiRoot() + '/logout';
   onLoginEvent: ReplaySubject<boolean> = new ReplaySubject<boolean>();
   $onLoginEvent = this.onLoginEvent.asObservable();
 
diff --git 
a/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
 
b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
index eb69b56cea..6af5baddd2 100644
--- 
a/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
+++ 
b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
@@ -38,7 +38,7 @@ export class AlertSearchDirective implements AfterViewInit, 
OnChanges {
     const el = elementRef.nativeElement;
     el.classList.add('editor');
 
-    ace.config.set('basePath', '/assets/ace');
+    ace.config.set('basePath', 'assets/ace');
 
     this.editor = ace.edit(el);
     this.editor.$blockScrolling = Infinity;
diff --git a/metron-interface/metron-alerts/src/index.html 
b/metron-interface/metron-alerts/src/index.html
index e051e27f78..2eba72b40b 100644
--- a/metron-interface/metron-alerts/src/index.html
+++ b/metron-interface/metron-alerts/src/index.html
@@ -16,7 +16,7 @@
 <head>
   <meta charset="utf-8">
   <title>Metron Alerts</title>
-  <base href="/">
+  <base href="./">
 
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
diff --git a/metron-interface/metron-rest/pom.xml 
b/metron-interface/metron-rest/pom.xml
index 52b01754b2..e6d5fb8086 100644
--- a/metron-interface/metron-rest/pom.xml
+++ b/metron-interface/metron-rest/pom.xml
@@ -39,6 +39,7 @@
         <spring.version>5.0.5.RELEASE</spring.version>
         <eclipse.link.version>2.6.4</eclipse.link.version>
         <jsonpath.version>2.4.0</jsonpath.version>
+        <jwt.version>4.41.2</jwt.version>
     </properties>
     <dependencies>
       <dependency>
@@ -426,6 +427,11 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+            <version>${jwt.version}</version>
+        </dependency>
     </dependencies>
 
     <dependencyManagement>
diff --git 
a/metron-interface/metron-rest/src/main/config/knox/conf/topologies/metron.xml 
b/metron-interface/metron-rest/src/main/config/knox/conf/topologies/metron.xml
new file mode 100644
index 0000000000..3a8897bc5d
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/config/knox/conf/topologies/metron.xml
@@ -0,0 +1,71 @@
+<?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.
+  -->
+<topology>
+
+  <gateway>
+    <provider>
+        <role>authentication</role>
+        <name>ShiroProvider</name>
+        <enabled>true</enabled>
+        <param>
+            <name>sessionTimeout</name>
+            <value>30</value>
+        </param>
+        <param>
+            <name>main.ldapRealm</name>
+            <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+        </param>
+        <param>
+            <name>main.ldapRealm.userDnTemplate</name>
+            <value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>
+        </param>
+        <param>
+            <name>main.ldapRealm.contextFactory.url</name>
+            <value>ldap://localhost:33389</value>
+        </param>
+        <param>
+            <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+            <value>simple</value>
+        </param>
+        <param>
+            <name>urls./**</name>
+            <value>authcBasic</value>
+        </param>
+    </provider>
+
+    <provider>
+      <role>identity-assertion</role>
+      <name>Default</name>
+      <enabled>true</enabled>
+    </provider>
+
+    <provider>
+      <role>authorization</role>
+      <name>AclsAuthz</name>
+      <enabled>true</enabled>
+    </provider>
+
+  </gateway>
+
+  <service>
+    <role>METRON-REST</role>
+    <url>http://localhost:8082</url>
+  </service>
+
+  <service>
+    <role>METRON-ALERTS</role>
+    <url>http://localhost:4201</url>
+  </service>
+
+</topology>
\ No newline at end of file
diff --git 
a/metron-interface/metron-rest/src/main/config/knox/data/services/alerts/rewrite.xml
 
b/metron-interface/metron-rest/src/main/config/knox/data/services/alerts/rewrite.xml
new file mode 100644
index 0000000000..9fecf9ed4c
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/config/knox/data/services/alerts/rewrite.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+<rules>
+  <rule dir="IN" name="METRON-ALERTS/metron-alerts/inbound/root" 
pattern="*://*:*/**/metron-alerts/">
+    <rewrite template="{$serviceUrl[METRON-ALERTS-UI]}/"/>
+  </rule>
+  <rule dir="IN" name="METRON-ALERTS/metron-alerts/inbound/path" 
pattern="*://*:*/**/metron-alerts/{**}">
+    <rewrite template="{$serviceUrl[METRON-ALERTS-UI]}/{**}"/>
+  </rule>
+  <rule dir="IN" name="METRON-ALERTS/metron-alerts/inbound/query" 
pattern="*://*:*/**/metron-alerts/{**}?{**}">
+    <rewrite template="{$serviceUrl[METRON-ALERTS]}/{**}?{**}"/>
+  </rule>
+</rules>
\ No newline at end of file
diff --git 
a/metron-interface/metron-rest/src/main/config/knox/data/services/alerts/service.xml
 
b/metron-interface/metron-rest/src/main/config/knox/data/services/alerts/service.xml
new file mode 100644
index 0000000000..a09be990de
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/config/knox/data/services/alerts/service.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+<service role="METRON-ALERTS" name="metron-alerts" version="0.6.1">
+  <routes>
+    <route path="/metron-alerts/"/>
+    <route path="/metron-alerts/**"/>
+    <route path="/metron-alerts/**?**"/>
+  </routes>
+  <dispatch 
classname="org.apache.hadoop.gateway.dispatch.PassAllHeadersDispatch"/>
+</service>
\ No newline at end of file
diff --git 
a/metron-interface/metron-rest/src/main/config/knox/data/services/rest/rewrite.xml
 
b/metron-interface/metron-rest/src/main/config/knox/data/services/rest/rewrite.xml
new file mode 100644
index 0000000000..fabed06985
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/config/knox/data/services/rest/rewrite.xml
@@ -0,0 +1,18 @@
+<?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.
+  -->
+<rules>
+  <rule dir="IN" name="METRON-REST/metron-rest/inbound" 
pattern="*://*:*/**/metron-rest/{path=**}?{**}">
+    <rewrite template="{$serviceUrl[METRON-REST]}/{path=**}?{**}"/>
+  </rule>
+</rules>
\ No newline at end of file
diff --git 
a/metron-interface/metron-rest/src/main/config/knox/data/services/rest/service.xml
 
b/metron-interface/metron-rest/src/main/config/knox/data/services/rest/service.xml
new file mode 100644
index 0000000000..d9bb56bced
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/config/knox/data/services/rest/service.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+<service role="METRON-REST" name="metron-rest" version="0.6.1">
+  <routes>
+    <route path="/metron-rest/**"/>
+  </routes>
+  <dispatch 
classname="org.apache.hadoop.gateway.dispatch.PassAllHeadersDispatch"/>
+</service>
\ No newline at end of file
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
index 80ac2bf3ab..b8a8306cdd 100644
--- 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/MetronRestConstants.java
@@ -25,6 +25,7 @@
   public static final String TEST_PROFILE = "test";
   public static final String LDAP_PROFILE = "ldap";
   public static final String DOCKER_PROFILE = "docker";
+  public static final String KNOX_PROFILE = "knox";
   public static final String CSRF_ENABLE_PROFILE = "csrf-enable";
 
   public static final String GROK_TEMP_PATH_SPRING_PROPERTY = "grok.path.temp";
@@ -71,6 +72,7 @@
   public static final String META_DAO_IMPL = "meta.dao.impl";
   public static final String META_DAO_SORT = "meta.dao.sort";
 
+  public static final String SECURITY_ROLE_PREFIX = "ROLE_";
   public static final String SECURITY_ROLE_USER = "USER";
   public static final String SECURITY_ROLE_ADMIN = "ADMIN";
 
@@ -87,4 +89,10 @@
   public static final String PCAP_PDML_SCRIPT_PATH_SPRING_PROPERTY = 
"pcap.pdml.script.path";
   public static final String PCAP_YARN_QUEUE_SPRING_PROPERTY = 
"pcap.yarn.queue";
   public static final String PCAP_FINALIZER_THREADPOOL_SIZE_SPRING_PROPERTY = 
"pcap.finalizer.threadpool.size";
+
+  public static final String LDAP_PROVIDER_URL_SPRING_PROPERTY = 
"ldap.provider.url";
+  public static final String LDAP_PROVIDER_USERDN_SPRING_PROPERTY = 
"ldap.provider.userdn";
+  public static final String LDAP_PROVIDER_PASSWORD_SPRING_PROPERTY = 
"ldap.provider.password";
+
+  public static final String KNOX_ROOT_SPRING_PROPERTY = "knox.root";
 }
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/KnoxSSOAuthenticationFilter.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/KnoxSSOAuthenticationFilter.java
new file mode 100644
index 0000000000..e6528f2159
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/KnoxSSOAuthenticationFilter.java
@@ -0,0 +1,281 @@
+/**
+ * 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.metron.rest.config;
+
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSObject;
+import com.nimbusds.jose.JWSVerifier;
+import com.nimbusds.jose.crypto.RSASSAVerifier;
+import com.nimbusds.jwt.SignedJWT;
+import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
+import org.apache.metron.rest.security.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.support.LdapNameBuilder;
+import 
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import 
org.springframework.security.web.authentication.WebAuthenticationDetails;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+import java.security.cert.CertificateException;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.apache.metron.rest.MetronRestConstants.SECURITY_ROLE_PREFIX;
+import static org.springframework.ldap.query.LdapQueryBuilder.query;
+
+/**
+ * This class is a Servlet Filter that authenticates a Knox SSO token.  The 
token is stored in a cookie and is
+ * verified against a public Knox key.  The token expiration and begin time 
are also validated.  Upon successful validation,
+ * a Spring Authentication object is built from the user name and user groups 
queried from LDAP.  Currently, user groups are
+ * mapped directly to Spring roles and prepended with "ROLE_".
+ */
+public class KnoxSSOAuthenticationFilter implements Filter {
+  private static final Logger LOG = 
LoggerFactory.getLogger(KnoxSSOAuthenticationFilter.class);
+
+  private String userSearchBase;
+  private Path knoxKeyFile;
+  private String knoxKeyString;
+  private String knoxCookie;
+  private LdapTemplate ldapTemplate;
+
+  public KnoxSSOAuthenticationFilter(String userSearchBase,
+                                     Path knoxKeyFile,
+                                     String knoxKeyString,
+                                     String knoxCookie,
+                                     LdapTemplate ldapTemplate) {
+    this.userSearchBase = userSearchBase;
+    this.knoxKeyFile = knoxKeyFile;
+    this.knoxKeyString = knoxKeyString;
+    this.knoxCookie = knoxCookie;
+    if (ldapTemplate == null) {
+      throw new IllegalStateException("KnoxSSO requires LDAP. You must add 
'ldap' to the active profiles.");
+    }
+    this.ldapTemplate = ldapTemplate;
+  }
+
+  @Override
+  public void init(FilterConfig filterConfig) {
+  }
+
+  @Override
+  public void destroy() {
+  }
+
+  /**
+   * Extracts the Knox token from the configured cookie.  If basic 
authentication headers are present, SSO authentication
+   * is skipped.
+   * @param request ServletRequest
+   * @param response ServletResponse
+   * @param chain FilterChain
+   * @throws IOException
+   * @throws ServletException
+   */
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain)
+          throws IOException, ServletException {
+    HttpServletRequest httpRequest = (HttpServletRequest) request;
+
+    // If a basic authentication header is present, use that to authenticate 
and skip SSO
+    String authHeader = httpRequest.getHeader("Authorization");
+    if (authHeader == null || !authHeader.startsWith("Basic")) {
+      String serializedJWT = getJWTFromCookie(httpRequest);
+      if (serializedJWT != null) {
+        SignedJWT jwtToken = null;
+        try {
+          jwtToken = SignedJWT.parse(serializedJWT);
+          String userName = jwtToken.getJWTClaimsSet().getSubject();
+          LOG.info("SSO login user : {} ", userName);
+          if (isValid(jwtToken, userName)) {
+            Authentication authentication = getAuthentication(userName, 
httpRequest);
+            
SecurityContextHolder.getContext().setAuthentication(authentication);
+          }
+        } catch (ParseException e) {
+          LOG.warn("Unable to parse the JWT token", e);
+        }
+      }
+    }
+    chain.doFilter(request, response);
+  }
+
+  /**
+   * Validates a Knox token with expiration and begin times and verifies the 
token with a public Knox key.
+   * @param jwtToken Knox token
+   * @param userName User name associated with the token
+   * @return Whether a token is valid or not
+   * @throws ParseException JWT Token could not be parsed.
+   */
+  protected boolean isValid(SignedJWT jwtToken, String userName) throws 
ParseException {
+    // Verify the user name is present
+    if (userName == null || userName.isEmpty()) {
+      LOG.info("Could not find user name in SSO token");
+      return false;
+    }
+
+    Date now = new Date();
+
+    // Verify the token has not expired
+    Date expirationTime = jwtToken.getJWTClaimsSet().getExpirationTime();
+    if (expirationTime != null && now.after(expirationTime)) {
+      LOG.info("SSO token expired: {} ", userName);
+      return false;
+    }
+
+    // Verify the token is not before time
+    Date notBeforeTime = jwtToken.getJWTClaimsSet().getNotBeforeTime();
+    if (notBeforeTime != null && now.before(notBeforeTime)) {
+      LOG.info("SSO token not yet valid: {} ", userName);
+      return false;
+    }
+
+    return validateSignature(jwtToken);
+  }
+
+  /**
+   * Verify the signature of the JWT token in this method. This method depends 
on
+   * the public key that was established during init based upon the provisioned
+   * public key. Override this method in subclasses in order to customize the
+   * signature verification behavior.
+   *
+   * @param jwtToken The token that contains the signature to be validated.
+   * @return valid true if signature verifies successfully; false otherwise
+   */
+  protected boolean validateSignature(SignedJWT jwtToken) {
+    // Verify the token signature algorithm was as expected
+    String receivedSigAlg = jwtToken.getHeader().getAlgorithm().getName();
+
+    if (!receivedSigAlg.equals(JWSAlgorithm.RS256.getName())) {
+      return false;
+    }
+
+    // Verify the token has been properly signed
+    if (JWSObject.State.SIGNED == jwtToken.getState()) {
+      LOG.debug("SSO token is in a SIGNED state");
+      if (jwtToken.getSignature() != null) {
+        LOG.debug("SSO token signature is not null");
+        try {
+          JWSVerifier verifier = new 
RSASSAVerifier(SecurityUtils.parseRSAPublicKey(getKnoxKey()));
+          if (jwtToken.verify(verifier)) {
+            LOG.debug("SSO token has been successfully verified");
+            return true;
+          } else {
+            LOG.warn("SSO signature verification failed. Please check the 
public key.");
+          }
+        } catch (Exception e) {
+          LOG.warn("Error while validating signature", e);
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Encapsulate the acquisition of the JWT token from HTTP cookies within the
+   * request.
+   *
+   * @param req ServletRequest to get the JWT token from
+   * @return serialized JWT token
+   */
+  protected String getJWTFromCookie(HttpServletRequest req) {
+    String serializedJWT = null;
+    Cookie[] cookies = req.getCookies();
+    if (cookies != null) {
+      for (Cookie cookie : cookies) {
+        LOG.debug(String.format("Found cookie: %s [%s]", cookie.getName(), 
cookie.getValue()));
+        if (knoxCookie.equals(cookie.getName())) {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug(knoxCookie + " cookie has been found and is being 
processed");
+          }
+          serializedJWT = cookie.getValue();
+          break;
+        }
+      }
+    } else {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug(knoxCookie + " not found");
+      }
+    }
+    return serializedJWT;
+  }
+
+  /**
+   * A public Knox key can either be passed in directly or read from a file.
+   * @return Public Knox key
+   * @throws IOException There was a problem reading the Knox key file.
+   */
+  private String getKnoxKey() throws IOException {
+    String knoxKey;
+    if ((this.knoxKeyString == null || this.knoxKeyString.isEmpty()) && 
this.knoxKeyFile != null) {
+      List<String> keyLines = Files.readAllLines(knoxKeyFile, 
StandardCharsets.UTF_8);
+      knoxKey = String.join("", keyLines);
+    } else {
+      knoxKey = this.knoxKeyString;
+    }
+    return knoxKey;
+  }
+
+  /**
+   * Builds the Spring Authentication object using the supplied user name and 
groups looked up from LDAP.  Groups are currently
+   * mapped directly to Spring roles by converting to upper case and 
prepending the name with "ROLE_".
+   * @param userName The username to build the Authentication object with.
+   * @param httpRequest HttpServletRequest
+   * @return Authentication object for the given user.
+   */
+  private Authentication getAuthentication(String userName, HttpServletRequest 
httpRequest) {
+    String ldapName = 
LdapNameBuilder.newInstance().add(userSearchBase).add("uid", 
userName).build().toString();
+
+    // Search ldap for a user's groups and convert to a Spring role
+    List<GrantedAuthority> grantedAuths = ldapTemplate.search(query()
+            .where("objectclass")
+            .is("groupOfNames")
+            .and("member")
+            .is(ldapName), (AttributesMapper<String>) attrs -> (String) 
attrs.get("cn").get())
+            .stream()
+            .map(group -> String.format("%s%s", SECURITY_ROLE_PREFIX, 
group.toUpperCase()))
+            .map(SimpleGrantedAuthority::new).collect(Collectors.toList());
+
+    final UserDetails principal = new User(userName, "", grantedAuths);
+    final UsernamePasswordAuthenticationToken authentication = new 
UsernamePasswordAuthenticationToken(
+            principal, "", grantedAuths);
+    WebAuthenticationDetails webDetails = new 
WebAuthenticationDetails(httpRequest);
+    authentication.setDetails(webDetails);
+    return authentication;
+  }
+
+}
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/LdapConfig.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/LdapConfig.java
new file mode 100644
index 0000000000..3bb4cd1195
--- /dev/null
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/LdapConfig.java
@@ -0,0 +1,52 @@
+/**
+ * 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.metron.rest.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.LdapContextSource;
+
+import static org.apache.metron.rest.MetronRestConstants.LDAP_PROFILE;
+import static 
org.apache.metron.rest.MetronRestConstants.LDAP_PROVIDER_PASSWORD_SPRING_PROPERTY;
+import static 
org.apache.metron.rest.MetronRestConstants.LDAP_PROVIDER_URL_SPRING_PROPERTY;
+import static 
org.apache.metron.rest.MetronRestConstants.LDAP_PROVIDER_USERDN_SPRING_PROPERTY;
+
+@Configuration
+@Profile(LDAP_PROFILE)
+public class LdapConfig {
+
+  @Autowired
+  private Environment environment;
+
+  @Bean
+  public LdapTemplate ldapTemplate() {
+    LdapContextSource contextSource = new LdapContextSource();
+
+    
contextSource.setUrl(environment.getProperty(LDAP_PROVIDER_URL_SPRING_PROPERTY));
+    
contextSource.setUserDn(environment.getProperty(LDAP_PROVIDER_USERDN_SPRING_PROPERTY));
+    
contextSource.setPassword(environment.getProperty(LDAP_PROVIDER_PASSWORD_SPRING_PROPERTY));
+    contextSource.afterPropertiesSet();
+
+    return new LdapTemplate(contextSource);
+  }
+
+}
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/SwaggerConfig.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/SwaggerConfig.java
index 564ff32896..d0da8cc861 100644
--- 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/SwaggerConfig.java
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/SwaggerConfig.java
@@ -17,22 +17,64 @@
  */
 package org.apache.metron.rest.config;
 
+import org.apache.metron.rest.MetronRestConstants;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
 import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.builders.PathSelectors;
 import springfox.documentation.builders.RequestHandlerSelectors;
 import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.paths.RelativePathProvider;
 import springfox.documentation.spring.web.plugins.Docket;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
+import javax.servlet.ServletContext;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.apache.metron.rest.MetronRestConstants.KNOX_PROFILE;
+
 @Configuration
 @EnableSwagger2
 public class SwaggerConfig {
+
+  @Autowired
+  private Environment environment;
+
+  @Autowired
+  ServletContext servletContext;
+
   @Bean
   public Docket api() {
-    return new Docket(DocumentationType.SWAGGER_2)
-            .select()
+    List<String> activeProfiles = 
Arrays.asList(environment.getActiveProfiles());
+    Docket docket = new Docket(DocumentationType.SWAGGER_2);
+    if (activeProfiles.contains(KNOX_PROFILE)) {
+      String knoxRoot = 
environment.getProperty(MetronRestConstants.KNOX_ROOT_SPRING_PROPERTY, 
String.class, "");
+      docket = docket.pathProvider(new RelativePathProvider (servletContext) {
+        @Override
+        protected String applicationPath() {
+          return knoxRoot;
+        }
+
+        @Override
+        protected String getDocumentationPath() {
+          return knoxRoot;
+        }
+
+        @Override
+        public String getApplicationBasePath() {
+          return knoxRoot;
+        }
+
+        @Override
+        public String getOperationPath(String operationPath) {
+          return knoxRoot + super.getOperationPath(operationPath);
+        }
+      });
+    }
+    return docket.select()
             
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
             .paths(PathSelectors.any())
             .build();
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/WebSecurityConfig.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/WebSecurityConfig.java
index 7ca3a46e4b..835889c6a9 100644
--- 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/WebSecurityConfig.java
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/config/WebSecurityConfig.java
@@ -20,8 +20,16 @@
 import static org.apache.metron.rest.MetronRestConstants.SECURITY_ROLE_ADMIN;
 import static org.apache.metron.rest.MetronRestConstants.SECURITY_ROLE_USER;
 
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.interfaces.RSAPublicKey;
 import java.util.Arrays;
 import java.util.List;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import javax.sql.DataSource;
 import org.apache.metron.rest.MetronRestConstants;
 import org.slf4j.Logger;
@@ -31,16 +39,32 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.env.Environment;
+import org.springframework.http.HttpMethod;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.security.authentication.ProviderManager;
 import 
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import 
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import 
org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import 
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import 
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.crypto.password.LdapShaPasswordEncoder;
 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
+import 
org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
+import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
+import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
+import 
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 import 
org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import 
org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
 import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -58,27 +82,49 @@
     @Autowired
     private DataSource dataSource;
 
+    @Autowired(required = false)
+    private LdapTemplate ldapTemplate;
+
     @Value("${ldap.provider.url}")
     private String providerUrl;
+
     @Value("${ldap.provider.userdn}")
     private String providerUserDn;
+
     @Value("${ldap.provider.password}")
     private String providerPassword;
+
     @Value("${ldap.user.dn.patterns}")
     private String userDnPatterns;
+
     @Value("${ldap.user.passwordAttribute}")
     private String passwordAttribute;
+
     @Value("${ldap.user.searchBase}")
     private String userSearchBase;
+
     @Value("${ldap.user.searchFilter}")
     private String userSearchFilter;
+
     @Value("${ldap.group.searchBase}")
     private String groupSearchBase;
+
     @Value("${ldap.group.roleAttribute}")
     private String groupRoleAttribute;
+
     @Value("${ldap.group.searchFilter}")
     private String groupSearchFilter;
 
+    @Value("${knox.sso.pubkeyFile:}")
+    private Path knoxKeyFile;
+
+    @Value("${knox.sso.pubkey:}")
+    private String knoxKeyString;
+
+    @Value("${knox.sso.cookie:hadoop-jwt}")
+    private String knoxCookie;
+
+
     @RequestMapping(value = {"/login", "/logout", "/sensors", "/sensors*/**"}, 
method = RequestMethod.GET)
     public String handleNGRequests() {
         return "forward:/index.html";
@@ -100,14 +146,21 @@ protected void configure(HttpSecurity http) throws 
Exception {
                 .and().httpBasic()
                 .and()
                 .logout()
+                .logoutUrl("/api/v1/logout")
                 .logoutSuccessHandler(new 
HttpStatusReturningLogoutSuccessHandler())
                 .invalidateHttpSession(true)
-                .deleteCookies("JSESSIONID");
-        if 
(Arrays.asList(environment.getActiveProfiles()).contains(MetronRestConstants.CSRF_ENABLE_PROFILE))
 {
+                .deleteCookies("JSESSIONID", knoxCookie);
+
+        List<String> activeProfiles = 
Arrays.asList(environment.getActiveProfiles());
+        if (activeProfiles.contains(MetronRestConstants.CSRF_ENABLE_PROFILE)) {
             
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
         } else {
             http.csrf().disable();
         }
+        if (activeProfiles.contains(MetronRestConstants.KNOX_PROFILE)) {
+          http.addFilterAt(new KnoxSSOAuthenticationFilter(userSearchBase, 
knoxKeyFile, knoxKeyString,
+                  knoxCookie, ldapTemplate), 
UsernamePasswordAuthenticationFilter.class);
+        }
     }
 
     @Autowired
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/AlertsUIController.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/AlertsUIController.java
index fe2968fe67..6125017d61 100644
--- 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/AlertsUIController.java
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/controller/AlertsUIController.java
@@ -18,6 +18,7 @@
 package org.apache.metron.rest.controller;
 
 import static org.apache.metron.rest.MetronRestConstants.SECURITY_ROLE_ADMIN;
+import static org.apache.metron.rest.MetronRestConstants.SECURITY_ROLE_PREFIX;
 
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -74,7 +75,7 @@
     }
   }
 
-  @Secured({"ROLE_" + SECURITY_ROLE_ADMIN})
+  @Secured({SECURITY_ROLE_PREFIX + SECURITY_ROLE_ADMIN})
   @ApiOperation(value = "Retrieves all users' settings.  Only users that are 
part of "
           + "the \"ROLE_ADMIN\" role are allowed to get all user settings.")
   @ApiResponses(value = {@ApiResponse(message = "List of all user settings", 
code = 200),
@@ -103,7 +104,7 @@
     return responseEntity;
   }
 
-  @Secured({"ROLE_" + SECURITY_ROLE_ADMIN})
+  @Secured({SECURITY_ROLE_PREFIX + SECURITY_ROLE_ADMIN})
   @ApiOperation(value = "Deletes a user's settings.  Only users that are part 
of "
           + "the \"ROLE_ADMIN\" role are allowed to delete user settings.")
   @ApiResponses(value = {@ApiResponse(message = "User settings were deleted", 
code = 200),
diff --git 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/security/SecurityUtils.java
 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/security/SecurityUtils.java
index ed10f145f9..5da1a06b30 100644
--- 
a/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/security/SecurityUtils.java
+++ 
b/metron-interface/metron-rest/src/main/java/org/apache/metron/rest/security/SecurityUtils.java
@@ -21,6 +21,15 @@
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetails;
 
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+
 public class SecurityUtils {
 
   /** Returns the username of the currently logged in user.
@@ -37,4 +46,28 @@ public static String getCurrentUser() {
     }
     return user;
   }
+
+  public static RSAPublicKey parseRSAPublicKey(String pem)
+          throws CertificateException, UnsupportedEncodingException {
+    String PEM_HEADER = "-----BEGIN CERTIFICATE-----\n";
+    String PEM_FOOTER = "\n-----END CERTIFICATE-----";
+    String fullPem = (pem.startsWith(PEM_HEADER) && pem.endsWith(PEM_FOOTER)) 
? pem : PEM_HEADER + pem + PEM_FOOTER;
+    PublicKey key = null;
+    try {
+      CertificateFactory fact = CertificateFactory.getInstance("X.509");
+      ByteArrayInputStream is = new 
ByteArrayInputStream(fullPem.getBytes(StandardCharsets.UTF_8));
+      X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
+      key = cer.getPublicKey();
+    } catch (CertificateException ce) {
+      String message = null;
+      if (pem.startsWith(PEM_HEADER)) {
+        message = "CertificateException - be sure not to include PEM header "
+                + "and footer in the PEM configuration element.";
+      } else {
+        message = "CertificateException - PEM may be corrupt";
+      }
+      throw new CertificateException(message, ce);
+    }
+    return (RSAPublicKey) key;
+  }
 }
diff --git 
a/metron-interface/metron-rest/src/main/scripts/install_metron_knox.sh 
b/metron-interface/metron-rest/src/main/scripts/install_metron_knox.sh
new file mode 100755
index 0000000000..befc294ebd
--- /dev/null
+++ b/metron-interface/metron-rest/src/main/scripts/install_metron_knox.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# 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.
+#
+METRON_VERSION=${project.version}
+METRON_HOME=${METRON_HOME:-/usr/metron/${METRON_VERSION}}
+KNOX_HOME=${KNOX_HOME:-/usr/hdp/current/knox-server}
+KNOX_METRON_REST_DIR=$KNOX_HOME/data/services/metron-rest/$METRON_VERSION
+KNOX_METRON_ALERTS_DIR=$KNOX_HOME/data/services/metron-alerts/$METRON_VERSION
+
+mkdir -p $KNOX_METRON_REST_DIR
+mkdir -p $KNOX_METRON_ALERTS_DIR
+
+cp $METRON_HOME/config/knox/data/services/rest/* $KNOX_METRON_REST_DIR
+cp $METRON_HOME/config/knox/data/services/alerts/* $KNOX_METRON_ALERTS_DIR
+cp $METRON_HOME/config/knox/conf/topologies/metron.xml 
$KNOX_HOME/conf/topologies


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to