Repository: metron
Updated Branches:
  refs/heads/feature/METRON-1663-knoxsso 28f4b5704 -> 54880ba8f


http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronAuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronAuthenticationProvider.java
 
b/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronAuthenticationProvider.java
new file mode 100644
index 0000000..42d8a2d
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronAuthenticationProvider.java
@@ -0,0 +1,60 @@
+/**
+ * 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.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+public class MetronAuthenticationProvider implements AuthenticationProvider {
+
+  @Override
+  public Authentication authenticate(Authentication authentication) throws 
AuthenticationException {
+    if (authentication != null) {
+      authentication = getSSOAuthentication(authentication);
+      if (authentication != null && authentication.isAuthenticated()) {
+        return authentication;
+      }
+    }
+    throw new MetronAuthenticationException("Authentication failed");
+  }
+
+  private Authentication getSSOAuthentication(Authentication authentication) {
+    return authentication;
+  }
+
+  @Override
+  public boolean supports(Class<?> authentication) {
+    return true;
+  }
+
+  public static List<GrantedAuthority> getAuthoritiesFromUGI(String userName) {
+    // TODO - if we have ldap, we can lookup groups for this user
+    
+    // TODO - if we have a default mapper we can use that
+    
+    List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
+    grantedAuths.add(new SimpleGrantedAuthority("USER"));
+    return grantedAuths;
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronSecurityConfig.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronSecurityConfig.java
 
b/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronSecurityConfig.java
new file mode 100644
index 0000000..7d3ec3b
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/main/java/org/apache/metron/ui/MetronSecurityConfig.java
@@ -0,0 +1,188 @@
+/**
+ * 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.ui;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.interfaces.RSAPublicKey;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+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.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import 
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@SuppressWarnings("deprecation")
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
+public class MetronSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MetronSecurityConfig.class);
+
+    @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.url}")
+    private String knoxUrl;
+
+    @Value("${knox.sso.cookie:hadoop-jwt}")
+    private String knoxCookie;
+
+    @Value("${knox.sso.originalUrl:originalUrl}")
+    private String knoxOriginalUrl;
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        // @formatter:off
+        http
+            
.authorizeRequests().antMatchers(HttpMethod.OPTIONS,"/**").permitAll().and()
+            .authorizeRequests().anyRequest().fullyAuthenticated()
+            .and()
+                .httpBasic()
+            .and()
+                .logout().disable();
+        // @formatter:on
+
+        // allow form based login if knox sso not in use
+        if (knoxUrl == null || knoxUrl.isEmpty()) {
+            http.formLogin();
+        }
+
+        
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER).sessionFixation();
+        if (this.knoxUrl != null && !this.knoxUrl.isEmpty()) {
+            http.addFilterAt(ssoAuthenticationFilter(), 
UsernamePasswordAuthenticationFilter.class);
+        }
+        http.headers().disable();
+        http.csrf().disable();
+    }
+
+    private KnoxSSOAuthenticationFilter ssoAuthenticationFilter() throws 
Exception {
+        String knoxKey;
+        if ((this.knoxKeyString == null || this.knoxKeyString.isEmpty()) && 
this.knoxKeyFile != null) {
+            List<String> keyLines = Files.readAllLines(knoxKeyFile, 
StandardCharsets.UTF_8);
+            if (keyLines != null) {
+                knoxKey = String.join("", keyLines);
+            } else {
+                knoxKey = "";
+            }
+        } else {
+            knoxKey = this.knoxKeyString;
+        }
+        try {
+            RSAPublicKey parseRSAPublicKey = 
KnoxSSOAuthenticationFilter.parseRSAPublicKey(knoxKey);
+            return new KnoxSSOAuthenticationFilter(authenticationProvider(), 
knoxUrl, knoxCookie, knoxOriginalUrl,
+                    parseRSAPublicKey);
+        } catch (Exception e) {
+            LOG.error("Cannot parse public key for KnoxSSO, please include the 
PEM string without certificate headers",
+                    e);
+            throw (e);
+        }
+    }
+
+    @Override
+    public void configure(AuthenticationManagerBuilder auth) throws Exception {
+        LOG.debug("Setting up LDAP authentication against %s", providerUrl);
+        // @formatter:off
+        if(this.providerUrl != null && !this.providerUrl.isEmpty()) {
+            auth.ldapAuthentication()
+                .userDnPatterns(userDnPatterns)
+                .userSearchBase(userSearchBase)
+                .userSearchFilter(userSearchFilter)
+                .groupRoleAttribute(groupRoleAttribute)
+                .groupSearchFilter(groupSearchFilter)
+                .groupSearchBase(groupSearchBase)
+                .contextSource()
+                    .url(providerUrl)
+                    .managerDn(providerUserDn)
+                    .managerPassword(providerPassword)
+                    .and()
+                .passwordCompare()
+                    .passwordEncoder(passwordEncoder())
+                    .passwordAttribute(passwordAttribute);
+        }
+        // @formatter:on
+        try {
+          auth
+              .authenticationProvider(authenticationProvider());
+        } catch (Exception e){ 
+          LOG.error("Cannot setup authentication", e);
+        }
+        auth.userDetailsService(userDetailsService());
+    }
+
+    @Bean
+    public MetronAuthenticationProvider authenticationProvider() {
+        return new MetronAuthenticationProvider();
+    }
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        // this currently uses plaintext passwords, which is not ideal
+        // TODO replace with a delegating encoder which runs through the good 
algos, or
+        // a config option based on the strength of passwords in the ldap store
+
+        return NoOpPasswordEncoder.getInstance();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/EmbeddedLdap.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/EmbeddedLdap.java
 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/EmbeddedLdap.java
new file mode 100644
index 0000000..a41ea7e
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/EmbeddedLdap.java
@@ -0,0 +1,164 @@
+/**
+ * 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.ui;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.directory.server.core.DefaultDirectoryService;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.partition.Partition;
+import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
+import 
org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
+import org.apache.directory.server.ldap.LdapService;
+import org.apache.directory.server.protocol.shared.SocketAcceptor;
+import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
+import org.apache.directory.server.xdbm.Index;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * A Bean based wrapper for an Embedded Apache Directory Server used to back
+ * LDAP Authentication.
+ */
+@Component
+public class EmbeddedLdap implements InitializingBean, DisposableBean {
+
+    public static final String EMBEDDED_LDAP_PROFILE = "embedded-ldap";
+    private Logger LOG = LoggerFactory.getLogger(this.getClass());
+
+    @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;
+
+    @Rule
+    public TemporaryFolder workdir = new TemporaryFolder();
+
+    private LdapService ldapService;
+
+    private DefaultDirectoryService directoryService;
+
+    private Partition partition;
+
+    @Override
+    public void destroy() throws Exception {
+        LOG.info("Stopping embedded LDAP");
+
+        ldapService.stop();
+        directoryService.shutdown();
+
+        workdir.delete();
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        workdir.create();
+
+        LOG.info("Starting embedded LDAP");
+        LOG.debug("Using temporary directory %s", workdir.toString());
+
+        directoryService = new DefaultDirectoryService();
+        directoryService.setWorkingDirectory(workdir.getRoot());
+        directoryService.getChangeLog().setEnabled(false);
+
+        partition = addPartition("testPartition", "dc=org");
+        addIndex("objectClass", "ou", "uid", "cn");
+
+        SocketAcceptor socketAcceptor = new SocketAcceptor(null);
+
+        Pattern p = Pattern.compile("ldaps?://([^:]*):(\\d*).*");
+        Matcher m = p.matcher(providerUrl);
+        int port;
+        if (m.matches()) {
+            port = Integer.parseInt(m.group(2));
+        } else {
+            port = 33389;
+        }
+
+        ldapService = new LdapService();
+        ldapService.setIpPort(port);
+        ldapService.setSearchBaseDn(userSearchBase);
+        ldapService.setDirectoryService(directoryService);
+        ldapService.setSocketAcceptor(socketAcceptor);
+
+        directoryService.startup();
+        ldapService.start();
+
+        // load default schema
+        applyLdif(new File("schema.ldif"));
+        LOG.debug("LDAP server started");
+    }
+
+    private Partition addPartition(String partitionId, String partitionDn) 
throws Exception {
+        Partition partition = new JdbmPartition();
+        partition.setId(partitionId);
+        partition.setSuffix(partitionDn);
+        directoryService.addPartition(partition);
+
+        return partition;
+    }
+
+    public void addIndex(String... attrs) {
+        HashSet<Index<?, ServerEntry>> indexedAttributes = new 
HashSet<Index<?, ServerEntry>>();
+
+        for (String attribute : attrs) {
+            indexedAttributes.add(new JdbmIndex<String, 
ServerEntry>(attribute));
+        }
+
+        ((JdbmPartition) partition).setIndexedAttributes(indexedAttributes);
+    }
+
+    public void applyLdif(File ldifFile) throws Exception {
+        new LdifFileLoader(directoryService.getAdminSession(), ldifFile, null, 
this.getClass().getClassLoader())
+                .execute();
+    }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/JWTTests.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/JWTTests.java
 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/JWTTests.java
new file mode 100644
index 0000000..0b3015b
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/JWTTests.java
@@ -0,0 +1,170 @@
+/**
+ * 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.ui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+
+import org.junit.Test;
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSObject;
+import com.nimbusds.jose.Payload;
+import com.nimbusds.jose.crypto.RSASSASigner;
+
+import net.minidev.json.JSONObject;
+
+public class JWTTests {
+    private static final String COOKIE_NAME = "hadoop-jwt";
+    private static final String knoxUrl = 
"https://localhost:8443/gateway/default/knoxsso";;
+    
+    private static final Payload DEFAULT_PAYLOAD = new Payload("{ \"sub\": 
\"test\" }");
+
+    @Test
+    public void testValidJWT() throws Exception {
+        KeyPair key = createKey();
+        requestThatSucceeds(tokenWithKey((RSAPrivateKey) 
key.getPrivate(),DEFAULT_PAYLOAD), key);
+    }
+
+    @Test
+    public void testInvalidJWT() throws Exception {
+        KeyPair key = createKey();
+        KeyPair badKey = createKey();
+        assertFalse(key.equals(badKey));
+        requestThatFails(tokenWithKey((RSAPrivateKey) 
badKey.getPrivate(),DEFAULT_PAYLOAD), key);
+    }
+
+    @Test()
+    public void testExpiredJWT() throws Exception {
+      Date date = new Date();
+      KeyPair key = createKey();
+      
+      JSONObject json = new JSONObject();
+      json.appendField("sub", "test");
+      json.appendField("exp", (date.getTime() - 60000) / 1000);
+      
+      Payload payload = new Payload(json);
+      JWSObject token = tokenWithKey((RSAPrivateKey) key.getPrivate(), 
payload);
+      
+      requestThatFails(token, key);
+    }
+    
+    @Test()
+    public void testNotYetJWT() throws Exception {
+      Date date = new Date();
+      KeyPair key = createKey();
+      
+      JSONObject json = new JSONObject();
+      json.appendField("sub", "test");
+      json.appendField("exp", (date.getTime() + 60000) / 1000);
+      json.appendField("nbf", (date.getTime() + 30000) / 1000);
+      
+      Payload payload = new Payload(json);
+      JWSObject token = tokenWithKey((RSAPrivateKey) key.getPrivate(), 
payload);
+      
+      requestThatFails(token, key);
+    }
+
+    @Test()
+    public void testCorrectTimeWindowJWT() throws Exception {
+      Date date = new Date();
+      KeyPair key = createKey();
+      
+      JSONObject json = new JSONObject();
+      json.appendField("sub", "test");
+      json.appendField("exp", (date.getTime() + 60000) / 1000);
+      json.appendField("nbf", (date.getTime() - 30000) / 1000);
+      
+      Payload payload = new Payload(json);
+      JWSObject token = tokenWithKey((RSAPrivateKey) key.getPrivate(), 
payload);
+      
+      requestThatSucceeds(token, key);
+    }
+
+    private void requestThatSucceeds(JWSObject token, KeyPair key) throws 
IOException, ServletException {
+      MockHttpServletRequest request = requestWithJWT(token);
+      MockHttpServletResponse response = new MockHttpServletResponse();
+      MockFilterChain chain = new MockFilterChain();
+
+      MetronAuthenticationProvider authenticationProvider = new 
MetronAuthenticationProvider();
+      KnoxSSOAuthenticationFilter knoxSSOAuthenticationFilter = new 
KnoxSSOAuthenticationFilter(
+              authenticationProvider, knoxUrl, null, null, (RSAPublicKey) 
key.getPublic());
+
+      knoxSSOAuthenticationFilter.doFilter(request, response, chain);
+
+      // ensure that the filter has passed a successful authentication context
+      Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication();
+      assertNotNull("Authentication object is set", authentication);
+      assertEquals("test", ((User) 
authentication.getPrincipal()).getUsername());
+    }
+
+    private void requestThatFails(JWSObject token, KeyPair key) throws 
IOException, ServletException {
+      MockHttpServletRequest request = requestWithJWT(token);
+      MockHttpServletResponse response = new MockHttpServletResponse();
+      MockFilterChain chain = new MockFilterChain();
+
+      MetronAuthenticationProvider authenticationProvider = new 
MetronAuthenticationProvider();
+      KnoxSSOAuthenticationFilter knoxSSOAuthenticationFilter = new 
KnoxSSOAuthenticationFilter(
+              authenticationProvider, knoxUrl, null, null, (RSAPublicKey) 
key.getPublic());
+
+      knoxSSOAuthenticationFilter.doFilter(request, response, chain);
+      
+      assertRedirectedToKnox(response);
+    }
+
+    private KeyPair createKey() throws Exception {
+        return KeyPairGenerator.getInstance("RSA").generateKeyPair();
+    }
+
+    private JWSObject tokenWithKey(RSAPrivateKey key, Payload payload) throws 
JOSEException {
+        JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.RS256), 
payload);
+        jwsObject.sign(new RSASSASigner(key));
+        return jwsObject;
+    }
+
+    private MockHttpServletRequest requestWithJWT(JWSObject jwt) {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setCookies(new Cookie(COOKIE_NAME, jwt.serialize()));
+        return request;
+    }
+
+    private static void assertRedirectedToKnox(MockHttpServletResponse 
response) {
+        assertTrue("Reponse is redirect to SSO", 
response.getHeader("Location").startsWith(knoxUrl));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/KnoxSSOAuthenticationFilterTests.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/KnoxSSOAuthenticationFilterTests.java
 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/KnoxSSOAuthenticationFilterTests.java
new file mode 100644
index 0000000..efaa62c
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/KnoxSSOAuthenticationFilterTests.java
@@ -0,0 +1,66 @@
+/**
+ * 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.ui;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.security.cert.CertificateException;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+
+import javax.servlet.ServletException;
+
+import org.junit.Test;
+import org.springframework.stereotype.Component;
+
+import com.nimbusds.jose.util.IOUtils;
+
+@Component
+public class KnoxSSOAuthenticationFilterTests {
+
+    @Test
+    public void testParsePemWithHeaders() throws CertificateException, 
ServletException, IOException {
+        RSAPublicKey parseRSAPublicKey = KnoxSSOAuthenticationFilter
+                
.parseRSAPublicKey(readFile("org/apache/metron/ui/headers.pem"));
+        assertNotNull(parseRSAPublicKey);
+    }
+
+    @Test
+    public void testParsePemWithoutHeaders() throws CertificateException, 
ServletException, IOException {
+        RSAPublicKey parseRSAPublicKey = 
KnoxSSOAuthenticationFilter.parseRSAPublicKey(readFile("org/apache/metron/ui/noheaders.pem"));
+        assertNotNull(parseRSAPublicKey);
+    }
+
+    @Test(expected = ServletException.class)
+    public void testInvalidPem() throws CertificateException, 
ServletException, IOException {
+        @SuppressWarnings("unused")
+        RSAPublicKey parseRSAPublicKey = 
KnoxSSOAuthenticationFilter.parseRSAPublicKey(readFile("org/apache/metron/ui/invalid.pem"));
+        fail();
+    }
+
+    private String readFile(String file) throws IOException {
+        ClassLoader cl = this.getClass().getClassLoader();
+        try (InputStream resourceAsStream = cl.getResourceAsStream(file)) {
+            return IOUtils.readInputStreamToString(resourceAsStream, 
Charset.defaultCharset());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/MetronAuthenticationProviderTests.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/MetronAuthenticationProviderTests.java
 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/MetronAuthenticationProviderTests.java
new file mode 100644
index 0000000..eba5341
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/MetronAuthenticationProviderTests.java
@@ -0,0 +1,33 @@
+/**
+ * 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.ui;
+
+import org.junit.Before;
+
+public class MetronAuthenticationProviderTests {
+  private MetronAuthenticationProvider authenticationProvider;
+  
+  @Before
+  public void setup() {
+    authenticationProvider = new MetronAuthenticationProvider();
+  }
+  
+  public void testGroupsFromUGI() {
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/config/TestSecurityConfig.java
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/config/TestSecurityConfig.java
 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/config/TestSecurityConfig.java
new file mode 100644
index 0000000..a47c74a
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/java/org/apache/metron/ui/config/TestSecurityConfig.java
@@ -0,0 +1,31 @@
+/**
+ * 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.ui.config;
+
+import org.apache.metron.ui.EmbeddedLdap;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class TestSecurityConfig {
+
+    @Bean
+    public EmbeddedLdap embeddedLdap() {
+        return new EmbeddedLdap();
+    }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/resources/application-embedded-ldap.yml
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/resources/application-embedded-ldap.yml
 
b/metron-interface/metron-ui-security/src/test/resources/application-embedded-ldap.yml
new file mode 100644
index 0000000..5c4d7e2
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/resources/application-embedded-ldap.yml
@@ -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.
+
+spring: 
+  logging:
+    level:
+      root: debug
+
+ldap:
+  provider:
+    url: ldap://localhost:33389
+    userdn: uid=admin,ou=people,dc=metron,dc=apache,dc=org
+    password: password
+  user:
+    dn.patterns: uid={0},ou=people,dc=metron,dc=apache,dc=org
+    passwordAttribute: userPassword
+    searchBase: ou=people,dc=metron,dc=apache,dc=org
+    searchFilter: ""
+  group:
+    searchBase: ou=groups,dc=metron,dc=apache,dc=org
+    searchFilter: "member={0}"
+    roleAttribute: "cn"

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/headers.pem
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/headers.pem
 
b/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/headers.pem
new file mode 100644
index 0000000..7153bb4
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/headers.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMx
+CzAJBgNVBAgMAkNBMQ8wDQYDVQQKDAZBcGFjaGUxGDAWBgNVBAMMD0NBIGludGVy
+bWVkaWF0ZTAeFw0xODA3MTExOTA0NTRaFw0yODEwMTYxOTA0NTRaMDsxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTEPMA0GA1UECgwGQXBhY2hlMQ4wDAYDVQQDDAVu
+b2RlMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6j8MIkAi4hZXd8
+rD+lmcQ6SmmUX8DrWKOu3cywUTcUR6ZfJQ+Lt0kZH2yDOPhpmr5TIEx7aTzAmloz
+ZUVoArcoqjGan7Np5Hy2vC1rDeqMbueQ7m4LSpwFRzqb9ZnFycq+U1Jo5nrHwVdy
+xfvo5yOYOgyWQT/upEsStiR0ADjyLPzTVQlErdAAVxKbRHF3ikWSvHzu8yoKcWAG
+n7CbShuOF0bIMOR9e7GtlSQH6JMxH17oEU98KiVRvJV52RKHpHZpPfDb36YvsgTy
+7ZczDmCQPNpU9hfV+vcgZEXFyrpxLgG7pHJBXPXWv8cw9rQLLim0297LNRpGAAz2
+Gc2todECAwEAAaOBrDCBqTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAz
+BglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmlj
+YXRlMB0GA1UdDgQWBBQWMdyJLWA4vgE90pAuRa4/z4S4kDAOBgNVHQ8BAf8EBAMC
+BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEAYDVR0RBAkwB4IFbm9kZTEwDQYJKoZI
+hvcNAQELBQADggIBAMdFhC4xDxGs7i/gKhgBCv1JicNqk6Y2OQsS8ohk64ansx1r
+uU0Rbx/pOsuD+d3ZuYeBaOYnHSLhExCcSxFjUlBkjS7aEigMxlHf2D+tYOgdcwlc
+SjMaqyFDke+mR0rm8I15HviLjjZy1bDLnb8UsozLtdU040/MAtx9uF7SqvYUsTqy
+alyfPeYZGpHZiFAmTcZ33uF3EByaSLACMVje0O1C9Xi/1v5Smp64NF15EF2DlHIv
+TAj88oG7eEivVWie41mx8s/8WpR6XE3WFuZSc+j4qndtzwvmzlaO/e/v64ZzTPTL
+SnrV424gtfZahjCb7+rSLQnSZShPeQessa1uF00xkCwlXuA7WXP9dAtOycySRsI+
+qy7vwD9Y5ZkZwFK8+8UnvySwwCSEHmy4zM0irA/XIKIRw7ahU3rxbkHgVCGh6Pyu
+kGfv/+Wy9yW461w0aYUTMrUrS429CBDY0ek3T9eQ5bieJRjOYOl/uuPH+L4VSCOS
+p2WIuXqqDMXqmxMUFNuaLYEg4Y51aLD0lkB+SH+tnOP5CZdufIKZRQhYiC+xcs2E
+2/VvbqjAMe9vzF6d7a5EqbTkdS9k8CNnmxCfN+FlSl/iqUI3HKLVxNs+2Sux+Dhl
+Nkt9qMcG2Gj0TxlqU43HrGeruVIxgC6Lj/QcIrc3Ddb1u7dccuNtF5UoqnVD
+-----END CERTIFICATE-----
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/invalid.pem
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/invalid.pem
 
b/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/invalid.pem
new file mode 100644
index 0000000..ffcd1bc
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/invalid.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+XIIEqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMx
+CzAJBgNVBAgMAkNBMQ8wDQYDVQQKDAZBcGFjaGUxGDAWBgNVBAMMD0NBIGludGVy
+bWVkaWF0ZTAeFw0xODA3MTExOTA0NTRaFw0yODEwMTYxOTA0NTRaMDsxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTEPMA0GA1UECgwGQXBhY2hlMQ4wDAYDVQQDDAVu
+b2RlMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6j8MIkAi4hZXd8
+rD+lmcQ6SmmUX8DrWKOu3cywUTcUR6ZfJQ+Lt0kZH2yDOPhpmr5TIEx7aTzAmloz
+ZUVoArcoqjGan7Np5Hy2vC1rDeqMbueQ7m4LSpwFRzqb9ZnFycq+U1Jo5nrHwVdy
+xfvo5yOYOgyWQT/upEsStiR0ADjyLPzTVQlErdAAVxKbRHF3ikWSvHzu8yoKcWAG
+n7CbShuOF0bIMOR9e7GtlSQH6JMxH17oEU98KiVRvJV52RKHpHZpPfDb36YvsgTy
+7ZczDmCQPNpU9hfV+vcgZEXFyrpxLgG7pHJBXPXWv8cw9rQLLim0297LNRpGAAz2
+Gc2todECAwEAAaOBrDCBqTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAz
+BglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmlj
+YXRlMB0GA1UdDgQWBBQWMdyJLWA4vgE90pAuRa4/z4S4kDAOBgNVHQ8BAf8EBAMC
+BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEAYDVR0RBAkwB4IFbm9kZTEwDQYJKoZI
+hvcNAQELBQADggIBAMdFhC4xDxGs7i/gKhgBCv1JicNqk6Y2OQsS8ohk64ansx1r
+uU0Rbx/pOsuD+d3ZuYeBaOYnHSLhExCcSxFjUlBkjS7aEigMxlHf2D+tYOgdcwlc
+SjMaqyFDke+mR0rm8I15HviLjjZy1bDLnb8UsozLtdU040/MAtx9uF7SqvYUsTqy
+alyfPeYZGpHZiFAmTcZ33uF3EByaSLACMVje0O1C9Xi/1v5Smp64NF15EF2DlHIv
+TAj88oG7eEivVWie41mx8s/8WpR6XE3WFuZSc+j4qndtzwvmzlaO/e/v64ZzTPTL
+SnrV424gtfZahjCb7+rSLQnSZShPeQessa1uF00xkCwlXuA7WXP9dAtOycySRsI+
+qy7vwD9Y5ZkZwFK8+8UnvySwwCSEHmy4zM0irA/XIKIRw7ahU3rxbkHgVCGh6Pyu
+kGfv/+Wy9yW461w0aYUTMrUrS429CBDY0ek3T9eQ5bieJRjOYOl/uuPH+L4VSCOS
+p2WIuXqqDMXqmxMUFNuaLYEg4Y51aLD0lkB+SH+tnOP5CZdufIKZRQhYiC+xcs2E
+2/VvbqjAMe9vzF6d7a5EqbTkdS9k8CNnmxCfN+FlSl/iqUI3HKLVxNs+2Sux+Dhl
+Nkt9qMcG2Gj0TxlqU43HrGeruVIxgC6Lj/QcIrc3Ddb1u7dccuNtF5UoqnVD
+-----END CERTIFICATE-----
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/noheaders.pem
----------------------------------------------------------------------
diff --git 
a/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/noheaders.pem
 
b/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/noheaders.pem
new file mode 100644
index 0000000..267decf
--- /dev/null
+++ 
b/metron-interface/metron-ui-security/src/test/resources/org/apache/metron/ui/noheaders.pem
@@ -0,0 +1,25 @@
+MIIEqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMx
+CzAJBgNVBAgMAkNBMQ8wDQYDVQQKDAZBcGFjaGUxGDAWBgNVBAMMD0NBIGludGVy
+bWVkaWF0ZTAeFw0xODA3MTExOTA0NTRaFw0yODEwMTYxOTA0NTRaMDsxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTEPMA0GA1UECgwGQXBhY2hlMQ4wDAYDVQQDDAVu
+b2RlMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6j8MIkAi4hZXd8
+rD+lmcQ6SmmUX8DrWKOu3cywUTcUR6ZfJQ+Lt0kZH2yDOPhpmr5TIEx7aTzAmloz
+ZUVoArcoqjGan7Np5Hy2vC1rDeqMbueQ7m4LSpwFRzqb9ZnFycq+U1Jo5nrHwVdy
+xfvo5yOYOgyWQT/upEsStiR0ADjyLPzTVQlErdAAVxKbRHF3ikWSvHzu8yoKcWAG
+n7CbShuOF0bIMOR9e7GtlSQH6JMxH17oEU98KiVRvJV52RKHpHZpPfDb36YvsgTy
+7ZczDmCQPNpU9hfV+vcgZEXFyrpxLgG7pHJBXPXWv8cw9rQLLim0297LNRpGAAz2
+Gc2todECAwEAAaOBrDCBqTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAz
+BglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmlj
+YXRlMB0GA1UdDgQWBBQWMdyJLWA4vgE90pAuRa4/z4S4kDAOBgNVHQ8BAf8EBAMC
+BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEAYDVR0RBAkwB4IFbm9kZTEwDQYJKoZI
+hvcNAQELBQADggIBAMdFhC4xDxGs7i/gKhgBCv1JicNqk6Y2OQsS8ohk64ansx1r
+uU0Rbx/pOsuD+d3ZuYeBaOYnHSLhExCcSxFjUlBkjS7aEigMxlHf2D+tYOgdcwlc
+SjMaqyFDke+mR0rm8I15HviLjjZy1bDLnb8UsozLtdU040/MAtx9uF7SqvYUsTqy
+alyfPeYZGpHZiFAmTcZ33uF3EByaSLACMVje0O1C9Xi/1v5Smp64NF15EF2DlHIv
+TAj88oG7eEivVWie41mx8s/8WpR6XE3WFuZSc+j4qndtzwvmzlaO/e/v64ZzTPTL
+SnrV424gtfZahjCb7+rSLQnSZShPeQessa1uF00xkCwlXuA7WXP9dAtOycySRsI+
+qy7vwD9Y5ZkZwFK8+8UnvySwwCSEHmy4zM0irA/XIKIRw7ahU3rxbkHgVCGh6Pyu
+kGfv/+Wy9yW461w0aYUTMrUrS429CBDY0ek3T9eQ5bieJRjOYOl/uuPH+L4VSCOS
+p2WIuXqqDMXqmxMUFNuaLYEg4Y51aLD0lkB+SH+tnOP5CZdufIKZRQhYiC+xcs2E
+2/VvbqjAMe9vzF6d7a5EqbTkdS9k8CNnmxCfN+FlSl/iqUI3HKLVxNs+2Sux+Dhl
+Nkt9qMcG2Gj0TxlqU43HrGeruVIxgC6Lj/QcIrc3Ddb1u7dccuNtF5UoqnVD
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/metron-ui-security/src/test/resources/schema.ldif
----------------------------------------------------------------------
diff --git a/metron-interface/metron-ui-security/src/test/resources/schema.ldif 
b/metron-interface/metron-ui-security/src/test/resources/schema.ldif
new file mode 100644
index 0000000..73d2dfd
--- /dev/null
+++ b/metron-interface/metron-ui-security/src/test/resources/schema.ldif
@@ -0,0 +1,77 @@
+# 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.
+
+version: 1
+
+dn: dc=org
+objectclass: domain
+objectclass: top
+dc: org
+
+dn: dc=apache,dc=org
+objectclass: domain
+objectclass: top
+dc: apache
+
+dn: dc=metron,dc=apache,dc=org
+objectclass: dcObject
+objectclass: domain
+objectclass: top
+dc: metron
+
+dn: ou=people,dc=metron,dc=apache,dc=org
+objectclass:top
+objectclass:organizationalUnit
+ou: people
+
+dn: ou=groups,dc=metron,dc=apache,dc=org
+objectclass:top
+objectclass:organizationalUnit
+ou: groups
+
+dn: uid=admin,ou=people,dc=metron,dc=apache,dc=org
+objectclass:top
+objectclass:person
+objectclass:organizationalPerson
+objectclass:inetOrgPerson
+cn: Admin
+sn: User
+uid: admin
+userPassword: password
+
+
+dn: uid=user,ou=people,dc=metron,dc=apache,dc=org
+objectclass:top
+objectclass:person
+objectclass:organizationalPerson
+objectclass:inetOrgPerson
+cn: Normal
+sn: User
+uid: user
+userPassword: password
+
+dn: cn=admin,ou=groups,dc=metron,dc=apache,dc=org
+objectClass: groupOfNames
+objectClass: top
+cn: admin
+member: uid=admin,ou=people,dc=metron,dc=apache,dc=org
+
+dn: cn=user,ou=groups,dc=metron,dc=apache,dc=org
+objectClass: groupOfNames
+objectClass: top
+cn: user
+member: uid=admin,ou=people,dc=metron,dc=apache,dc=org
+member: uid=user,ou=people,dc=metron,dc=apache,dc=org

http://git-wip-us.apache.org/repos/asf/metron/blob/54880ba8/metron-interface/pom.xml
----------------------------------------------------------------------
diff --git a/metron-interface/pom.xml b/metron-interface/pom.xml
index e6ccd2d..844f213 100644
--- a/metron-interface/pom.xml
+++ b/metron-interface/pom.xml
@@ -39,11 +39,24 @@
         </license>
     </licenses>
     <modules>
+        <module>metron-ui-security</module>
+        <module>metron-ui-host</module>
         <module>metron-config</module>
+        <module>metron-config-host</module>
         <module>metron-alerts</module>
+        <module>metron-alerts-host</module>
         <module>metron-rest</module>
         <module>metron-rest-client</module>
     </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
+        <spring.boot.version>2.0.1.RELEASE</spring.boot.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>junit</groupId>

Reply via email to