You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/02/27 12:02:21 UTC

[13/27] tinkerpop git commit: Some cleanup

Some cleanup


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6a9c6674
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6a9c6674
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6a9c6674

Branch: refs/heads/master
Commit: 6a9c6674ca80fac28a4c74e00e00d91aefc829dd
Parents: c849295
Author: HadoopMarc <vt...@xs4all.nl>
Authored: Fri Jan 13 20:42:51 2017 +0100
Committer: HadoopMarc <vt...@xs4all.nl>
Committed: Wed Jan 18 20:08:00 2017 +0100

----------------------------------------------------------------------
 .../gremlin/server/auth/JaasKrbUtil.java        |   9 +-
 .../gremlin/server/auth/Krb5Authenticator.java  |  22 +-
 .../tinkerpop/gremlin/server/AuditLogTest.java  | 322 -------------------
 .../tinkerpop/gremlin/server/AuthKrb5Test.java  | 263 ---------------
 .../GremlinServerAuditLogIntegrateTest.java     | 322 +++++++++++++++++++
 .../GremlinServerAuthKrb5IntegrateTest.java     | 235 ++++++++++++++
 .../tinkerpop/gremlin/server/KdcFixture.java    |   2 +-
 7 files changed, 569 insertions(+), 606 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java
index ad87d58..6a2e8d3 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java
@@ -53,8 +53,7 @@ public final class JaasKrbUtil {
 
     private JaasKrbUtil() { }
 
-    public static Subject loginUsingPassword(
-            String principal, String password) throws LoginException {
+    public static Subject loginUsingPassword(String principal, String password) throws LoginException {
         Set<Principal> principals = new HashSet<Principal>();
         principals.add(new KerberosPrincipal(principal));
 
@@ -69,8 +68,7 @@ public final class JaasKrbUtil {
         return loginContext.getSubject();
     }
 
-    public static Subject loginUsingTicketCache(
-            String principal, File cacheFile) throws LoginException {
+    public static Subject loginUsingTicketCache(String principal, File cacheFile) throws LoginException {
         Set<Principal> principals = new HashSet<Principal>();
         principals.add(new KerberosPrincipal(principal));
 
@@ -84,8 +82,7 @@ public final class JaasKrbUtil {
         return loginContext.getSubject();
     }
 
-    public static Subject loginUsingKeytab(
-            String principal, File keytabFile) throws LoginException {
+    public static Subject loginUsingKeytab(String principal, File keytabFile) throws LoginException {
         Set<Principal> principals = new HashSet<Principal>();
         principals.add(new KerberosPrincipal(principal));
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java
index 57a4259..275dba6 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java
@@ -36,7 +36,7 @@ import java.util.Map;
 
 
 /**
- * A Kerberos implementation of an {@link Authenticator}
+ * A Kerberos (GSSAPI) implementation of an {@link Authenticator}
  *
  * @author Marc de Lignie
  */
@@ -102,10 +102,10 @@ public class Krb5Authenticator implements Authenticator {
     }
 
     /*
-     * Invoked by:
-     *   https://github.com/apache/tinkerpop/blob/3.1.1-incubating/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAuthenticationHandler.java
+     * Krb5SaslAuthenticator is invoked by:
+     *   org.apache.tinkerpop.gremlin.server.handler.SaslAuthenticationHandler
      * Negotiates with evaluateChallenge() of the generic sasl handler in gremlin console:
-     *   https://github.com/apache/tinkerpop/blob/3.1.1-incubating/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
+     *   org.apache.tinkerpop.gremlin.driver.Handler.java
      * See also:
      *   https://docs.oracle.com/javase/8/docs/technotes/guides/security/sasl/sasl-refguide.html
      *   https://docs.oracle.com/javase/8/docs/api/org/ietf/jgss/GSSContext.html
@@ -120,13 +120,11 @@ public class Krb5Authenticator implements Authenticator {
             try {
                 // For sasl properties regarding GSSAPI, see:
                 //   https://docs.oracle.com/javase/8/docs/technotes/guides/security/sasl/sasl-refguide.html#SERVER
-                // Rely on GSSAPI defaults for Sasl.MAX_BUFFER and "javax.security.sasl.sendmaxbuffer"
-                // Sasl policy properties are not relevant here, because the sasl mechanisme is not negotiated
-                // Kerberos implementations do not handle Sasl.QOP values reliably; rather use SSL for enhanced privacy,
-                // see https://issues.apache.org/jira/browse/HIVE-8377
+                // Rely on GSSAPI defaults for Sasl.MAX_BUFFER and Sasl.QOP. Note, however, that gremlin-driver has
+                // Sasl.SERVER_AUTH fixed to true (mutual authentication) and one can configure SSL for enhanced confidentiality,
+                // Sasl policy properties for negotiating the authenticatin mechanism are not relevant here, because
+                // GSSAPI is the only available mechanism for this authenticator
                 final Map props = new HashMap<String, Object>();
-                if (!System.getProperty(Sasl.QOP, "").equals(""))
-                    logger.warn("Gremlin server uses default Sasl.QOP values, use SSL for enhanced privacy");
                 final String[] principalParts = principalName.split("/|@");
                 if (principalParts.length < 3) throw new IllegalArgumentException("Use principal name of format 'service/fqdn@kdcrealm'");
                 saslServer = Sasl.createSaslServer(mechanism, principalParts[0], principalParts[1], props, Krb5SaslAuthenticator.this);
@@ -139,9 +137,6 @@ public class Krb5Authenticator implements Authenticator {
         /*
          * This method is based on the handle() method from:
          *   https://github.com/apache/directory-kerby/blob/kerby-all-1.0.0-RC2/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/sasl/SaslAppServer.java
-         * Other example sources:
-         *   https://gist.github.com/honza889/1347ddee89311dd636d5 (APL)
-         *   https://github.com/wildfly-security/jboss-sasl/blob/master/src/test/java/org/jboss/sasl/test/ServerCallbackHandler.java (GPL)
          */
         @Override
         public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
@@ -188,7 +183,6 @@ public class Krb5Authenticator implements Authenticator {
         }
 
         @Override
-        // todo: apply for audit logging, see related todo in gremlin-server/.../SaslAuthenticationHandler.java
         public AuthenticatedUser getAuthenticatedUser() throws AuthenticationException {
             logger.debug("getAuthenticatedUser called: " + saslServer.getAuthorizationID());
             return new AuthenticatedUser(saslServer.getAuthorizationID());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuditLogTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuditLogTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuditLogTest.java
deleted file mode 100644
index b2f0fe8..0000000
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuditLogTest.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * 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.tinkerpop.gremlin.server;
-
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.apache.log4j.Logger;
-import org.apache.log4j.spi.LoggingEvent;
-import static org.apache.log4j.Level.INFO;
-import org.apache.tinkerpop.gremlin.driver.Client;
-import org.apache.tinkerpop.gremlin.driver.Cluster;
-import org.apache.tinkerpop.gremlin.driver.Channelizer;
-import org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer;
-import org.apache.tinkerpop.gremlin.server.channel.NioChannelizer;
-import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
-import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
-import org.apache.tinkerpop.gremlin.server.auth.AllowAllAuthenticator;
-import org.apache.tinkerpop.gremlin.server.auth.Krb5Authenticator;
-import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator;
-import static org.apache.tinkerpop.gremlin.server.AuthKrb5Test.TESTCONSOLE;
-import static org.apache.tinkerpop.gremlin.server.GremlinServer.AUDIT_LOGGER_NAME;
-import org.apache.tinkerpop.gremlin.util.Log4jRecordingAppender;
-import org.slf4j.LoggerFactory;
-
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-
-/**
- * @author Marc de Lignie
- *
- * Note: like other descendents of AbstractGremlinServerIntegrationTest this testsuite assumes that tests are
- *       run sequentially and thus the server variable can be reused.
- */
-public class AuditLogTest extends AbstractGremlinServerIntegrationTest {
-    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AuditLogTest.class);
-    private Log4jRecordingAppender recordingAppender = null;
-
-    private final ObjectMapper mapper = new ObjectMapper();
-    private final Base64.Encoder encoder = Base64.getUrlEncoder();
-
-    private static final boolean AUDIT_LOG_ENABLED = true;
-    private static final boolean AUDIT_LOG_DISABLED = false;
-
-    private KdcFixture kdcServer;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        try {
-            final String buildDir = System.getProperty("build.dir");
-            kdcServer = new KdcFixture(buildDir +
-                    "/test-classes/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf");
-            kdcServer.setUp();
-        } catch(Exception e)  {
-            logger.warn(e.getMessage());
-        }
-        super.setUp();
-    }
-
-    @Before
-    public void setupForEachTest() {
-        recordingAppender = new Log4jRecordingAppender();
-        final Logger rootLogger = Logger.getRootLogger();
-        rootLogger.addAppender(recordingAppender);
-    }
-
-    @After
-    public void teardownForEachTest() throws Exception {
-        final Logger rootLogger = Logger.getRootLogger();
-        rootLogger.removeAppender(recordingAppender);
-        kdcServer.close();
-    }
-
-    /**
-     * Configure specific Gremlin Server settings for specific tests.
-     */
-    @Override
-    public Settings overrideSettings(final Settings settings) {
-        settings.host = kdcServer.hostname;
-        final Settings.SslSettings sslConfig = new Settings.SslSettings();
-        sslConfig.enabled = false;
-        settings.ssl = sslConfig;
-        final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings();
-        settings.authentication = authSettings;
-        authSettings.enableAuditLog = AUDIT_LOG_ENABLED;
-        authSettings.className = Krb5Authenticator.class.getName();
-        final Map<String,Object> authConfig = new HashMap<>();
-        authSettings.config = authConfig;
-
-        final String nameOfTest = name.getMethodName();
-        switch (nameOfTest) {
-            case "shouldAuditLogWithAllowAllAuthenticator":
-                authSettings.className = AllowAllAuthenticator.class.getName();
-                break;
-            case "shouldAuditLogWithSimpleAuthenticator":
-                authSettings.className = SimpleAuthenticator.class.getName();
-                authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties");
-                break;
-            case "shouldNotAuditLogWhenDisabled":
-                authSettings.enableAuditLog = AUDIT_LOG_DISABLED;
-            case "shouldAuditLogWithKrb5Authenticator":
-                authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath());
-                authConfig.put("principal", kdcServer.serverPrincipal);
-                break;
-            case "shouldAuditLogWithNioTransport":
-                settings.channelizer = NioChannelizer.class.getName();
-                authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath());
-                authConfig.put("principal", kdcServer.serverPrincipal);
-                break;
-            case "shouldAuditLogWithHttpTransport":
-                settings.host = "localhost";
-                settings.channelizer = HttpChannelizer.class.getName();
-                authSettings.className = SimpleAuthenticator.class.getName();
-                authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties");
-                break;
-        }
-        return settings;
-    }
-
-    @Test
-    public void shouldAuditLogWithAllowAllAuthenticator() throws Exception {
-
-        final Cluster cluster = TestClientFactory.build().addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-
-        // WebSocketChannelizer does not add SaslAuthenticationHandler, so no authenticated user log line available
-        assertTrue(recordingAppender.logMatchesAny(AUDIT_LOGGER_NAME, INFO, "User with address .*? requested: 1\\+1"));
-        assertTrue(recordingAppender.logMatchesAny(AUDIT_LOGGER_NAME, INFO, "User with address .*? requested: 1\\+2"));
-        assertTrue(recordingAppender.logMatchesAny(AUDIT_LOGGER_NAME, INFO, "User with address .*? requested: 1\\+3"));
-    }
-
-    @Test
-    public void shouldAuditLogWithSimpleAuthenticator() throws Exception {
-        final String username = "stephen";
-        final String password = "password";
-
-        final Cluster cluster = TestClientFactory.build().credentials(username, password)
-                .addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-
-        final String simpleAuthenticatorName = SimpleAuthenticator.class.getSimpleName();
-        final String authMsg = recordingAppender.getMessages().stream()
-                .filter( msg -> msg.toString().contains("by " + simpleAuthenticatorName) ).iterator().next();
-        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
-        m.find();
-        final String address = m.group(1);
-
-        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
-                String.format("User %s with address %s authenticated by %s", username, address, simpleAuthenticatorName)));
-        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
-                String.format("User with address %s requested: 1+1", address)));
-        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
-                String.format("User with address %s requested: 1+2", address)));
-        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
-                String.format("User with address %s requested: 1+3", address)));
-    }
-
-    @Test
-    public void shouldAuditLogWithKrb5Authenticator() throws Exception {
-        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
-                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-
-        final List<LoggingEvent> log = recordingAppender.getEvents();
-        final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
-        final LoggingEvent authEvent = auditEvents
-                .filter(event -> event.getMessage().toString().contains("Krb5Authenticator")).iterator().next();
-        final String authMsg = authEvent.getMessage().toString();
-        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
-        m.find();
-        final String address = m.group(1);
-        assertTrue(authEvent.getLevel() == INFO && authMsg.equals(
-                String.format("User %s with address %s authenticated by Krb5Authenticator", kdcServer.clientPrincipalName, address)));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1+1", address))));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1+2", address))));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1+3", address))));
-    }
-
-    @Test
-    public void shouldNotAuditLogWhenDisabled() throws Exception {
-        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
-                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-
-        final List<LoggingEvent> log = recordingAppender.getEvents();
-        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().matches("User .*? with address .*? authenticated by Krb5Authenticator")));
-        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().matches("User with address .*? requested: 1\\+1")));
-        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().matches("User with address .*? requested: 1\\+2")));
-        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-            item.getMessage().toString().matches("User with address .*? requested: 1\\+3")));
-    }
-
-    @Test
-    public void shouldAuditLogWithNioTransport() throws Exception {
-        // ToDo issue (outside scope of this suite): .channelizer(Channelizer.NioChannelizer.class) fails
-        final Cluster cluster = TestClientFactory.build().channelizer(Channelizer.NioChannelizer.class.getName())
-                .jaasEntry(TESTCONSOLE).protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-
-        final List<LoggingEvent> log = recordingAppender.getEvents();
-        final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
-        final LoggingEvent authEvent = auditEvents
-                .filter(event -> event.getMessage().toString().contains("Krb5Authenticator")).iterator().next();
-        final String authMsg = authEvent.getMessage().toString();
-        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
-        m.find();
-        final String address = m.group(1);
-        assertTrue(authEvent.getLevel() == INFO && authMsg.equals(
-                String.format("User %s with address %s authenticated by Krb5Authenticator", kdcServer.clientPrincipalName, address)));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1+1", address))));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1+2", address))));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1+3", address))));
-    }
-
-    @Test
-    public void shouldAuditLogWithHttpTransport() throws Exception {
-        final CloseableHttpClient httpclient = HttpClients.createDefault();
-        final HttpGet httpget = new HttpGet(TestClientFactory.createURLString("?gremlin=1-1"));
-        httpget.addHeader("Authorization", "Basic " + encoder.encodeToString("stephen:password".getBytes()));
-
-        final CloseableHttpResponse response = httpclient.execute(httpget);
-        assertEquals(200, response.getStatusLine().getStatusCode());
-        assertEquals("application/json", response.getEntity().getContentType().getValue());
-        final String json = EntityUtils.toString(response.getEntity());
-        final JsonNode node = mapper.readTree(json);
-        response.close();
-        assertEquals(0, node.get("result").get("data").get(0).intValue());
-
-        final List<LoggingEvent> log = recordingAppender.getEvents();
-        final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
-        final LoggingEvent authEvent = auditEvents
-                .filter(event -> event.getMessage().toString().contains("SimpleAuthenticator")).iterator().next();
-        final String authMsg = authEvent.getMessage().toString();
-        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
-        m.find();
-        final String address = m.group(1);
-        assertTrue(authEvent.getLevel() == INFO && authMsg.equals(
-                String.format("User %s with address %s authenticated by SimpleAuthenticator", "stephen", address)));
-        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
-                item.getMessage().toString().equals(String.format("User with address %s requested: 1-1", address))));
-    }
-
-    //ToDo: test with two clients
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuthKrb5Test.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuthKrb5Test.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuthKrb5Test.java
deleted file mode 100644
index 11b873c..0000000
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AuthKrb5Test.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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.tinkerpop.gremlin.server;
-
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.apache.log4j.Logger;
-import org.apache.tinkerpop.gremlin.driver.Client;
-import org.apache.tinkerpop.gremlin.driver.Cluster;
-import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
-import org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0;
-import org.apache.tinkerpop.gremlin.server.auth.Krb5Authenticator;
-import org.apache.tinkerpop.gremlin.util.Log4jRecordingAppender;
-import org.ietf.jgss.GSSException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import javax.security.auth.login.LoginException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-
-
-/**
- * @author Marc de Lignie
- *
- * Todo: change back to integrate test later on
- */
-public class AuthKrb5Test extends AbstractGremlinServerIntegrationTest {
-    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AuthKrb5Test.class);
-    private Log4jRecordingAppender recordingAppender = null;
-
-    static final String TESTCONSOLE = "GremlinConsole";
-    static final String TESTCONSOLE_NOT_LOGGED_IN = "UserNotLoggedIn";
-
-    private KdcFixture kdcServer;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        setupForEachTest();
-        try {
-            final String buildDir = System.getProperty("build.dir");
-            kdcServer = new KdcFixture(buildDir +
-                    "/test-classes/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf");
-            kdcServer.setUp();
-        } catch(Exception e)  {
-            logger.warn(e.getMessage());
-        }
-        super.setUp();
-    }
-
-    public void setupForEachTest() {
-        recordingAppender = new Log4jRecordingAppender();
-        final Logger rootLogger = Logger.getRootLogger();
-        rootLogger.addAppender(recordingAppender);
-    }
-
-    @After
-    public void teardownForEachTest() throws Exception {
-        final Logger rootLogger = Logger.getRootLogger();
-        rootLogger.removeAppender(recordingAppender);
-        kdcServer.close();
-    }
-
-    /**
-     * Configure specific Gremlin Server settings for specific tests.
-     */
-    @Override
-    public Settings overrideSettings(final Settings settings) {
-        settings.host = kdcServer.hostname;
-        final Settings.SslSettings sslConfig = new Settings.SslSettings();
-        sslConfig.enabled = false;
-        settings.ssl = sslConfig;
-        final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings();
-        settings.authentication = authSettings;
-        authSettings.className = Krb5Authenticator.class.getName();
-        final Map<String,Object> authConfig = new HashMap<>();
-        authConfig.put("principal", kdcServer.serverPrincipal);
-        authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath());
-        authSettings.config = authConfig;
-
-        final String nameOfTest = name.getMethodName();
-        switch (nameOfTest) {
-            case "shouldAuthenticateWithDefaults":
-            case "shouldFailWithoutClientJaasEntry":
-            case "shouldFailWithoutClientTicketCache":
-                break;
-            case "shouldFailWithNonexistentServerPrincipal":
-                authConfig.put("principal", "no-service");
-                break;
-            case "shouldFailWithEmptyServerKeytab":
-                final File keytabFile = new File(".", "no-file");
-                authConfig.put("keytab", keytabFile);
-                break;
-            case "shouldFailWithWrongServerKeytab":
-                final String principal = "no-principal/somehost@TEST.COM";
-                try { kdcServer.createPrincipal(principal); } catch(Exception e) {
-                    logger.error("Cannot create principal in overrideSettings(): " + e.getMessage());
-                };
-                authConfig.put("principal", principal);
-                break;
-            case "shouldAuthenticateWithQop":
-                break;
-        }
-        return settings;
-    }
-
-    /**
-     * Defaults from TestClientFactory:
-     * private int port = 45940;
-     * private MessageSerializer serializer = Serializers.GRYO_V1D0.simpleInstance();
-     * private int nioPoolSize = Runtime.getRuntime().availableProcessors();
-     * private int workerPoolSize = Runtime.getRuntime().availableProcessors() * 2;
-     * private int minConnectionPoolSize = ConnectionPool.MIN_POOL_SIZE;
-     * private int maxConnectionPoolSize = ConnectionPool.MAX_POOL_SIZE;
-     * private int minSimultaneousUsagePerConnection = ConnectionPool.MIN_SIMULTANEOUS_USAGE_PER_CONNECTION;
-     * private int maxSimultaneousUsagePerConnection = ConnectionPool.MAX_SIMULTANEOUS_USAGE_PER_CONNECTION;
-     * private int maxInProcessPerConnection = Connection.MAX_IN_PROCESS;
-     * private int minInProcessPerConnection = Connection.MIN_IN_PROCESS;
-     * private int maxWaitForConnection = Connection.MAX_WAIT_FOR_CONNECTION;
-     * private int maxWaitForSessionClose = Connection.MAX_WAIT_FOR_SESSION_CLOSE;
-     * private int maxContentLength = Connection.MAX_CONTENT_LENGTH;
-     * private int reconnectInitialDelay = Connection.RECONNECT_INITIAL_DELAY;
-     * private int reconnectInterval = Connection.RECONNECT_INTERVAL;
-     * private int resultIterationBatchSize = Connection.RESULT_ITERATION_BATCH_SIZE;
-     * private long keepAliveInterval = Connection.KEEP_ALIVE_INTERVAL;
-     * private String channelizer = Channelizer.WebSocketChannelizer.class.getName();
-     * private boolean enableSsl = false;
-     * private String trustCertChainFile = null;
-     * private String keyCertChainFile = null;
-     * private String keyFile = null;
-     * private String keyPassword = null;
-     * private SslContext sslContext = null;
-     * private LoadBalancingStrategy loadBalancingStrategy = new LoadBalancingStrategy.RoundRobin();
-     * private AuthProperties authProps = new AuthProperties();
-     */
-    @Test
-    public void shouldAuthenticateWithDefaults() throws Exception {
-        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
-            .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldFailWithoutClientJaasEntry() throws Exception {
-        final Cluster cluster = TestClientFactory.build().protocol(kdcServer.serverPrincipalName)
-                .addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            client.submit("1+1").all().get();
-            fail("This should not succeed as the client config does not contain a JaasEntry");
-        } catch(Exception ex) {
-            final Throwable root = ExceptionUtils.getRootCause(ex);
-            assertEquals(GSSException.class, root.getClass());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldFailWithoutClientTicketCache() throws Exception {
-        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE_NOT_LOGGED_IN)
-                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            client.submit("1+1").all().get();
-            fail("This should not succeed as the client config does not contain a valid ticket cache");
-        } catch(Exception ex) {
-            final Throwable root = ExceptionUtils.getRootCause(ex);
-            assertEquals(LoginException.class, root.getClass());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldFailWithNonexistentServerPrincipal() throws Exception {
-        assertTrue(recordingAppender.logContainsAny("WARN - Failed to login to kdc"));
-    }
-
-    @Test
-    public void shouldFailWithEmptyServerKeytab() throws Exception {
-        assertTrue(recordingAppender.logContainsAny("WARN - Failed to login to kdc"));
-    }
-
-    @Test
-    public void shouldFailWithWrongServerKeytab() throws Exception {
-        assertTrue(recordingAppender.logContainsAny("WARN - Failed to login to kdc"));
-    }
-
-    @Test
-    public void shouldAuthenticateWithQop() throws Exception {
-        final String oldQop = System.getProperty("javax.security.sasl.qop", "");
-        System.setProperty("javax.security.sasl.qop", "auth-conf");
-        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
-                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
-        final Client client = cluster.connect();
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-            System.setProperty("javax.security.sasl.qop", oldQop);
-        }
-    }
-
-//    ToDo: Unclear how to test this
-//    @Test
-//    public void shouldFailWithAuthIdUnequalAuthzId() throws Exception {
-//        server = new GremlinServerAuthKrb5Integrate(getServerPrincipal(), serviceKeytabFile);
-//        server.setUp();
-//    }
-
-
-    @Test
-    public void shouldAuthenticateWithSerializeResultToString() throws Exception {
-        MessageSerializer serializer = new GryoMessageSerializerV1d0();
-        Map config = new HashMap<String, Object>();
-        config.put("serializeResultToString", true);
-        serializer.configure(config, null);
-        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
-                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).serializer(serializer).create();
-        final Client client = cluster.connect();
-        try {
-            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
-            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
-        } finally {
-            cluster.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
new file mode 100644
index 0000000..32c8451
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
@@ -0,0 +1,322 @@
+/*
+ * 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.tinkerpop.gremlin.server;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+import static org.apache.log4j.Level.INFO;
+import org.apache.tinkerpop.gremlin.driver.Client;
+import org.apache.tinkerpop.gremlin.driver.Cluster;
+import org.apache.tinkerpop.gremlin.driver.Channelizer;
+import org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer;
+import org.apache.tinkerpop.gremlin.server.channel.NioChannelizer;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.apache.tinkerpop.gremlin.server.auth.AllowAllAuthenticator;
+import org.apache.tinkerpop.gremlin.server.auth.Krb5Authenticator;
+import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator;
+import static org.apache.tinkerpop.gremlin.server.GremlinServerAuthKrb5IntegrateTest.TESTCONSOLE;
+import static org.apache.tinkerpop.gremlin.server.GremlinServer.AUDIT_LOGGER_NAME;
+import org.apache.tinkerpop.gremlin.util.Log4jRecordingAppender;
+import org.slf4j.LoggerFactory;
+
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ * @author Marc de Lignie
+ *
+ * Note: like other descendents of AbstractGremlinServerIntegrationTest this test suite assumes that tests are
+ *       run sequentially and thus the server and kdcServer variables can be reused.
+ */
+public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerIntegrationTest {
+    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GremlinServerAuditLogIntegrateTest.class);
+    private Log4jRecordingAppender recordingAppender = null;
+
+    private final ObjectMapper mapper = new ObjectMapper();
+    private final Base64.Encoder encoder = Base64.getUrlEncoder();
+
+    private static final boolean AUDIT_LOG_ENABLED = true;
+    private static final boolean AUDIT_LOG_DISABLED = false;
+
+    private KdcFixture kdcServer;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        try {
+            final String buildDir = System.getProperty("build.dir");
+            kdcServer = new KdcFixture(buildDir +
+                    "/test-classes/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf");
+            kdcServer.setUp();
+        } catch(Exception e)  {
+            logger.warn(e.getMessage());
+        }
+        super.setUp();
+    }
+
+    @Before
+    public void setupForEachTest() {
+        recordingAppender = new Log4jRecordingAppender();
+        final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.addAppender(recordingAppender);
+    }
+
+    @After
+    public void teardownForEachTest() throws Exception {
+        final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.removeAppender(recordingAppender);
+        kdcServer.close();
+    }
+
+    /**
+     * Configure specific Gremlin Server settings for specific tests.
+     */
+    @Override
+    public Settings overrideSettings(final Settings settings) {
+        settings.host = kdcServer.hostname;
+        final Settings.SslSettings sslConfig = new Settings.SslSettings();
+        sslConfig.enabled = false;
+        settings.ssl = sslConfig;
+        final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings();
+        settings.authentication = authSettings;
+        authSettings.enableAuditLog = AUDIT_LOG_ENABLED;
+        authSettings.className = Krb5Authenticator.class.getName();
+        final Map<String,Object> authConfig = new HashMap<>();
+        authSettings.config = authConfig;
+
+        final String nameOfTest = name.getMethodName();
+        switch (nameOfTest) {
+            case "shouldAuditLogWithAllowAllAuthenticator":
+                authSettings.className = AllowAllAuthenticator.class.getName();
+                break;
+            case "shouldAuditLogWithSimpleAuthenticator":
+                authSettings.className = SimpleAuthenticator.class.getName();
+                authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties");
+                break;
+            case "shouldNotAuditLogWhenDisabled":
+                authSettings.enableAuditLog = AUDIT_LOG_DISABLED;
+            case "shouldAuditLogWithKrb5Authenticator":
+                authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath());
+                authConfig.put("principal", kdcServer.serverPrincipal);
+                break;
+            case "shouldAuditLogWithNioTransport":
+                settings.channelizer = NioChannelizer.class.getName();
+                authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath());
+                authConfig.put("principal", kdcServer.serverPrincipal);
+                break;
+            case "shouldAuditLogWithHttpTransport":
+                settings.host = "localhost";
+                settings.channelizer = HttpChannelizer.class.getName();
+                authSettings.className = SimpleAuthenticator.class.getName();
+                authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties");
+                break;
+        }
+        return settings;
+    }
+
+    @Test
+    public void shouldAuditLogWithAllowAllAuthenticator() throws Exception {
+
+        final Cluster cluster = TestClientFactory.build().addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+
+        // WebSocketChannelizer does not add SaslAuthenticationHandler for AllowAllAuthenticator,
+        // so no authenticated user log line available
+        assertTrue(recordingAppender.logMatchesAny(AUDIT_LOGGER_NAME, INFO, "User with address .*? requested: 1\\+1"));
+        assertTrue(recordingAppender.logMatchesAny(AUDIT_LOGGER_NAME, INFO, "User with address .*? requested: 1\\+2"));
+        assertTrue(recordingAppender.logMatchesAny(AUDIT_LOGGER_NAME, INFO, "User with address .*? requested: 1\\+3"));
+    }
+
+    @Test
+    public void shouldAuditLogWithSimpleAuthenticator() throws Exception {
+        final String username = "stephen";
+        final String password = "password";
+
+        final Cluster cluster = TestClientFactory.build().credentials(username, password)
+                .addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+
+        final String simpleAuthenticatorName = SimpleAuthenticator.class.getSimpleName();
+        final String authMsg = recordingAppender.getMessages().stream()
+                .filter( msg -> msg.toString().contains("by " + simpleAuthenticatorName) ).iterator().next();
+        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
+        m.find();
+        final String address = m.group(1);
+
+        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
+                String.format("User %s with address %s authenticated by %s", username, address, simpleAuthenticatorName)));
+        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
+                String.format("User with address %s requested: 1+1", address)));
+        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
+                String.format("User with address %s requested: 1+2", address)));
+        assertTrue(recordingAppender.logContainsAny(AUDIT_LOGGER_NAME, INFO,
+                String.format("User with address %s requested: 1+3", address)));
+    }
+
+    @Test
+    public void shouldAuditLogWithKrb5Authenticator() throws Exception {
+        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
+                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+
+        final List<LoggingEvent> log = recordingAppender.getEvents();
+        final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
+        final LoggingEvent authEvent = auditEvents
+                .filter(event -> event.getMessage().toString().contains("Krb5Authenticator")).iterator().next();
+        final String authMsg = authEvent.getMessage().toString();
+        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
+        m.find();
+        final String address = m.group(1);
+        assertTrue(authEvent.getLevel() == INFO && authMsg.equals(
+                String.format("User %s with address %s authenticated by Krb5Authenticator", kdcServer.clientPrincipalName, address)));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1+1", address))));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1+2", address))));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1+3", address))));
+    }
+
+    @Test
+    public void shouldNotAuditLogWhenDisabled() throws Exception {
+        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
+                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+
+        final List<LoggingEvent> log = recordingAppender.getEvents();
+        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().matches("User .*? with address .*? authenticated by Krb5Authenticator")));
+        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().matches("User with address .*? requested: 1\\+1")));
+        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().matches("User with address .*? requested: 1\\+2")));
+        assertFalse(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+            item.getMessage().toString().matches("User with address .*? requested: 1\\+3")));
+    }
+
+    @Test
+    public void shouldAuditLogWithNioTransport() throws Exception {
+        final Cluster cluster = TestClientFactory.build().channelizer(Channelizer.NioChannelizer.class.getName())
+                .jaasEntry(TESTCONSOLE).protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+
+        final List<LoggingEvent> log = recordingAppender.getEvents();
+        final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
+        final LoggingEvent authEvent = auditEvents
+                .filter(event -> event.getMessage().toString().contains("Krb5Authenticator")).iterator().next();
+        final String authMsg = authEvent.getMessage().toString();
+        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
+        m.find();
+        final String address = m.group(1);
+        assertTrue(authEvent.getLevel() == INFO && authMsg.equals(
+                String.format("User %s with address %s authenticated by Krb5Authenticator", kdcServer.clientPrincipalName, address)));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1+1", address))));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1+2", address))));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1+3", address))));
+    }
+
+    @Test
+    public void shouldAuditLogWithHttpTransport() throws Exception {
+        final CloseableHttpClient httpclient = HttpClients.createDefault();
+        final HttpGet httpget = new HttpGet(TestClientFactory.createURLString("?gremlin=1-1"));
+        httpget.addHeader("Authorization", "Basic " + encoder.encodeToString("stephen:password".getBytes()));
+
+        final CloseableHttpResponse response = httpclient.execute(httpget);
+        assertEquals(200, response.getStatusLine().getStatusCode());
+        assertEquals("application/json", response.getEntity().getContentType().getValue());
+        final String json = EntityUtils.toString(response.getEntity());
+        final JsonNode node = mapper.readTree(json);
+        response.close();
+        assertEquals(0, node.get("result").get("data").get(0).intValue());
+
+        final List<LoggingEvent> log = recordingAppender.getEvents();
+        final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
+        final LoggingEvent authEvent = auditEvents
+                .filter(event -> event.getMessage().toString().contains("SimpleAuthenticator")).iterator().next();
+        final String authMsg = authEvent.getMessage().toString();
+        final Matcher m = Pattern.compile(".*?([\\d.:]+).*?").matcher(authMsg);
+        m.find();
+        final String address = m.group(1);
+        assertTrue(authEvent.getLevel() == INFO && authMsg.equals(
+                String.format("User %s with address %s authenticated by SimpleAuthenticator", "stephen", address)));
+        assertTrue(log.stream().anyMatch(item -> item.getLevel() == INFO &&
+                item.getMessage().toString().equals(String.format("User with address %s requested: 1-1", address))));
+    }
+
+    //ToDo: test with two clients
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthKrb5IntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthKrb5IntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthKrb5IntegrateTest.java
new file mode 100644
index 0000000..9573208
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthKrb5IntegrateTest.java
@@ -0,0 +1,235 @@
+/*
+ * 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.tinkerpop.gremlin.server;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.log4j.Logger;
+import org.apache.tinkerpop.gremlin.driver.Client;
+import org.apache.tinkerpop.gremlin.driver.Cluster;
+import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
+import org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0;
+import org.apache.tinkerpop.gremlin.server.auth.Krb5Authenticator;
+import org.apache.tinkerpop.gremlin.util.Log4jRecordingAppender;
+import org.ietf.jgss.GSSException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.login.LoginException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+
+/**
+ * @author Marc de Lignie
+ *
+ */
+public class GremlinServerAuthKrb5IntegrateTest extends AbstractGremlinServerIntegrationTest {
+    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GremlinServerAuthKrb5IntegrateTest.class);
+    private Log4jRecordingAppender recordingAppender = null;
+
+    static final String TESTCONSOLE = "GremlinConsole";
+    static final String TESTCONSOLE_NOT_LOGGED_IN = "UserNotLoggedIn";
+
+    private KdcFixture kdcServer;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        setupForEachTest();
+        try {
+            final String buildDir = System.getProperty("build.dir");
+            kdcServer = new KdcFixture(buildDir +
+                    "/test-classes/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf");
+            kdcServer.setUp();
+        } catch(Exception e)  {
+            logger.warn(e.getMessage());
+        }
+        super.setUp();
+    }
+
+    public void setupForEachTest() {
+        recordingAppender = new Log4jRecordingAppender();
+        final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.addAppender(recordingAppender);
+    }
+
+    @After
+    public void teardownForEachTest() throws Exception {
+        final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.removeAppender(recordingAppender);
+        kdcServer.close();
+    }
+
+    /**
+     * Configure specific Gremlin Server settings for specific tests.
+     */
+    @Override
+    public Settings overrideSettings(final Settings settings) {
+        settings.host = kdcServer.hostname;
+        final Settings.SslSettings sslConfig = new Settings.SslSettings();
+        sslConfig.enabled = false;
+        settings.ssl = sslConfig;
+        final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings();
+        settings.authentication = authSettings;
+        authSettings.className = Krb5Authenticator.class.getName();
+        final Map<String,Object> authConfig = new HashMap<>();
+        authConfig.put("principal", kdcServer.serverPrincipal);
+        authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath());
+        authSettings.config = authConfig;
+
+        final String nameOfTest = name.getMethodName();
+        switch (nameOfTest) {
+            case "shouldAuthenticateWithDefaults":
+            case "shouldFailWithoutClientJaasEntry":
+            case "shouldFailWithoutClientTicketCache":
+                break;
+            case "shouldFailWithNonexistentServerPrincipal":
+                authConfig.put("principal", "no-service");
+                break;
+            case "shouldFailWithEmptyServerKeytab":
+                final File keytabFile = new File(".", "no-file");
+                authConfig.put("keytab", keytabFile);
+                break;
+            case "shouldFailWithWrongServerKeytab":
+                final String principal = "no-principal/somehost@TEST.COM";
+                try { kdcServer.createPrincipal(principal); } catch(Exception e) {
+                    logger.error("Cannot create principal in overrideSettings(): " + e.getMessage());
+                };
+                authConfig.put("principal", principal);
+                break;
+            case "shouldAuthenticateWithQop":
+                break;
+        }
+        return settings;
+    }
+
+    @Test
+    public void shouldAuthenticateWithDefaults() throws Exception {
+        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
+                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldFailWithoutClientJaasEntry() throws Exception {
+        final Cluster cluster = TestClientFactory.build().protocol(kdcServer.serverPrincipalName)
+                .addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            client.submit("1+1").all().get();
+            fail("This should not succeed as the client config does not contain a JaasEntry");
+        } catch(Exception ex) {
+            final Throwable root = ExceptionUtils.getRootCause(ex);
+            assertEquals(GSSException.class, root.getClass());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldFailWithoutClientTicketCache() throws Exception {
+        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE_NOT_LOGGED_IN)
+                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            client.submit("1+1").all().get();
+            fail("This should not succeed as the client config does not contain a valid ticket cache");
+        } catch(Exception ex) {
+            final Throwable root = ExceptionUtils.getRootCause(ex);
+            assertEquals(LoginException.class, root.getClass());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldFailWithNonexistentServerPrincipal() throws Exception {
+        assertTrue(recordingAppender.logContainsAny("WARN - Failed to login to kdc"));
+    }
+
+    @Test
+    public void shouldFailWithEmptyServerKeytab() throws Exception {
+        assertTrue(recordingAppender.logContainsAny("WARN - Failed to login to kdc"));
+    }
+
+    @Test
+    public void shouldFailWithWrongServerKeytab() throws Exception {
+        assertTrue(recordingAppender.logContainsAny("WARN - Failed to login to kdc"));
+    }
+
+    @Test
+    public void shouldAuthenticateWithQop() throws Exception {
+        final String oldQop = System.getProperty("javax.security.sasl.qop", "");
+        System.setProperty("javax.security.sasl.qop", "auth-conf");
+        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
+                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).create();
+        final Client client = cluster.connect();
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+            System.setProperty("javax.security.sasl.qop", oldQop);
+        }
+    }
+
+//    ToDo: Unclear how to test this
+//    @Test
+//    public void shouldFailWithAuthIdUnequalAuthzId() throws Exception {
+//        server = new GremlinServerAuthKrb5Integrate(getServerPrincipal(), serviceKeytabFile);
+//        server.setUp();
+//    }
+
+
+    // This test backs a fix in gremlin-driver (cd628b251f6956c826df20c89177680fe120ff99)
+    // Maybe gremlin-driver needs its own test with client.submit("[1,2,3] as byte[]")
+    @Test
+    public void shouldAuthenticateWithSerializeResultToString() throws Exception {
+        MessageSerializer serializer = new GryoMessageSerializerV1d0();
+        Map config = new HashMap<String, Object>();
+        config.put("serializeResultToString", true);
+        serializer.configure(config, null);
+        final Cluster cluster = TestClientFactory.build().jaasEntry(TESTCONSOLE)
+                .protocol(kdcServer.serverPrincipalName).addContactPoint(kdcServer.hostname).serializer(serializer).create();
+        final Client client = cluster.connect();
+        try {
+            assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+            assertEquals(3, client.submit("1+2").all().get().get(0).getInt());
+            assertEquals(4, client.submit("1+3").all().get().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a9c6674/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java
index 7ff2f06..db19c96 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java
@@ -79,7 +79,7 @@ public class KdcFixture {
         try {
             hostname = Inet4Address.getLocalHost().getCanonicalHostName().toLowerCase();
         } catch (Exception e) {
-            logger.error("Hostname not found");
+            logger.error("Hostname not found: " + e.getMessage());
         }
         return hostname;
     }