// For each class, first ACL in the array specifies the allowed entries
        // and second ACL specifies blocked entries.
        // For each class, first MachineList in the array specifies the allowed entries
        // and second MachineList specifies blocked entries.
        /// <summary>Authorize the user to access the protocol being used.</summary>
        /// <param name="user">user accessing the service</param>
        /// <param name="protocol">service being accessed</param>
        /// <param name="conf">configuration to use</param>
        /// <param name="addr">InetAddress of the client</param>
        /// <exception cref="AuthorizationException">on authorization failure</exception>
        /// <exception cref="Org.Apache.Hadoop.Security.Authorize.AuthorizationException"/>
        public virtual void Authorize(UserGroupInformation user, Type protocol, Configuration
                                      conf, IPAddress addr)
        {
            AccessControlList[] acls  = protocolToAcls[protocol];
            MachineList[]       hosts = protocolToMachineLists[protocol];
            if (acls == null || hosts == null)
            {
                throw new AuthorizationException("Protocol " + protocol + " is not known.");
            }
            // get client principal key to verify (if available)
            KerberosInfo krbInfo         = SecurityUtil.GetKerberosInfo(protocol, conf);
            string       clientPrincipal = null;

            if (krbInfo != null)
            {
                string clientKey = krbInfo.ClientPrincipal();
                if (clientKey != null && !clientKey.IsEmpty())
                {
                    try
                    {
                        clientPrincipal = SecurityUtil.GetServerPrincipal(conf.Get(clientKey), addr);
                    }
                    catch (IOException e)
                    {
                        throw (AuthorizationException)Extensions.InitCause(new AuthorizationException
                                                                               ("Can't figure out Kerberos principal name for connection from " + addr + " for user="******" protocol=" + protocol), e);
                    }
                }
            }
            if ((clientPrincipal != null && !clientPrincipal.Equals(user.GetUserName())) || acls
                .Length != 2 || !acls[0].IsUserAllowed(user) || acls[1].IsUserAllowed(user))
            {
                Auditlog.Warn(AuthzFailedFor + user + " for protocol=" + protocol + ", expected client Kerberos principal is "
                              + clientPrincipal);
                throw new AuthorizationException("User " + user + " is not authorized for protocol "
                                                 + protocol + ", expected client Kerberos principal is " + clientPrincipal);
            }
            if (addr != null)
            {
                string hostAddress = addr.GetHostAddress();
                if (hosts.Length != 2 || !hosts[0].Includes(hostAddress) || hosts[1].Includes(hostAddress
                                                                                              ))
                {
                    Auditlog.Warn(AuthzFailedFor + " for protocol=" + protocol + " from host = " + hostAddress
                                  );
                    throw new AuthorizationException("Host " + hostAddress + " is not authorized for protocol "
                                                     + protocol);
                }
            }
            Auditlog.Info(AuthzSuccessfulFor + user + " for protocol=" + protocol);
        }