@Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
        if (msg instanceof FullHttpMessage) {
            final FullHttpMessage request = (FullHttpMessage) msg;
            if (!request.headers().contains("Authorization")) {
                sendError(ctx, UNAUTHORIZED, INCORRECT_CREDENTIALS_MESSAGE);
                ReferenceCountUtil.release(msg);
                return;
            }

            // strip off "Basic " from the Authorization header (RFC 2617)
            final String basic = "Basic ";
            final String authorizationHeader = request.headers().get("Authorization");
            if (!authorizationHeader.startsWith(basic)) {
                sendError(ctx, UNAUTHORIZED, INCORRECT_CREDENTIALS_MESSAGE);
                ReferenceCountUtil.release(msg);
                return;
            }
            byte[] decodedUserPass;
            try {
                final String encodedUserPass = authorizationHeader.substring(basic.length());
                decodedUserPass = decoder.decode(encodedUserPass);
            } catch (IndexOutOfBoundsException | IllegalArgumentException ex) {
                sendError(ctx, UNAUTHORIZED, ex.getMessage());
                ReferenceCountUtil.release(msg);
                return;
            }
            final String authorization = new String(decodedUserPass, StandardCharsets.UTF_8);
            final String[] split = authorization.split(":");
            if (split.length != 2) {
                sendError(ctx, UNAUTHORIZED, INCORRECT_CREDENTIALS_MESSAGE);
                ReferenceCountUtil.release(msg);
                return;
            }

            final Map<String,String> credentials = new HashMap<>();
            credentials.put(PROPERTY_USERNAME, split[0]);
            credentials.put(PROPERTY_PASSWORD, split[1]);

            String address = ctx.channel().remoteAddress().toString();
            if (address.startsWith("/") && address.length() > 1) address = address.substring(1);
            credentials.put(PROPERTY_ADDRESS, address);

            try {
                final AuthenticatedUser user = authenticator.authenticate(credentials);
                ctx.channel().attr(StateKey.AUTHENTICATED_USER).set(user);
                ctx.fireChannelRead(request);
                // User name logged with the remote socket address and authenticator classname for audit logging
                if (settings.enableAuditLog) {
                    final String[] authClassParts = authenticator.getClass().toString().split("[.]");
                    auditLogger.info("User {} with address {} authenticated by {}",
                            credentials.get(PROPERTY_USERNAME), address, authClassParts[authClassParts.length - 1]);
                }
            } catch (AuthenticationException ae) {
                sendError(ctx, UNAUTHORIZED, ae.getMessage());
                ReferenceCountUtil.release(msg);
            }
        }
    }
Implements basic HTTP authentication for use with the {@link HttpGremlinEndpointHandler} and HTTP based API calls.

@author Stephen Mallette (http://stephen.genoprime.com)
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpBasicAuthenticationHandler.java