@Test
  public void testACLTableAccess() throws Exception {
    final Configuration conf = TEST_UTIL.getConfiguration();

    // Superuser
    User superUser = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });

    // Global users
    User globalRead = User.createUserForTesting(conf, "globalRead", new String[0]);
    User globalWrite = User.createUserForTesting(conf, "globalWrite", new String[0]);
    User globalCreate = User.createUserForTesting(conf, "globalCreate", new String[0]);
    User globalAdmin = User.createUserForTesting(conf, "globalAdmin", new String[0]);
    SecureTestUtil.grantGlobal(TEST_UTIL, globalRead.getShortName(), Action.READ);
    SecureTestUtil.grantGlobal(TEST_UTIL, globalWrite.getShortName(), Action.WRITE);
    SecureTestUtil.grantGlobal(TEST_UTIL, globalCreate.getShortName(), Action.CREATE);
    SecureTestUtil.grantGlobal(TEST_UTIL, globalAdmin.getShortName(), Action.ADMIN);

    // Namespace users
    User nsRead = User.createUserForTesting(conf, "nsRead", new String[0]);
    User nsWrite = User.createUserForTesting(conf, "nsWrite", new String[0]);
    User nsCreate = User.createUserForTesting(conf, "nsCreate", new String[0]);
    User nsAdmin = User.createUserForTesting(conf, "nsAdmin", new String[0]);
    SecureTestUtil.grantOnNamespace(TEST_UTIL, nsRead.getShortName(),
      testTable.getTableName().getNamespaceAsString(), Action.READ);
    SecureTestUtil.grantOnNamespace(TEST_UTIL, nsWrite.getShortName(),
      testTable.getTableName().getNamespaceAsString(), Action.WRITE);
    SecureTestUtil.grantOnNamespace(TEST_UTIL, nsCreate.getShortName(),
      testTable.getTableName().getNamespaceAsString(), Action.CREATE);
    SecureTestUtil.grantOnNamespace(TEST_UTIL, nsAdmin.getShortName(),
      testTable.getTableName().getNamespaceAsString(), Action.ADMIN);

    // Table users
    User tableRead = User.createUserForTesting(conf, "tableRead", new String[0]);
    User tableWrite = User.createUserForTesting(conf, "tableWrite", new String[0]);
    User tableCreate = User.createUserForTesting(conf, "tableCreate", new String[0]);
    User tableAdmin = User.createUserForTesting(conf, "tableAdmin", new String[0]);
    SecureTestUtil.grantOnTable(TEST_UTIL, tableRead.getShortName(), testTable.getTableName(), null,
      null, Action.READ);
    SecureTestUtil.grantOnTable(TEST_UTIL, tableWrite.getShortName(), testTable.getTableName(),
      null, null, Action.WRITE);
    SecureTestUtil.grantOnTable(TEST_UTIL, tableCreate.getShortName(), testTable.getTableName(),
      null, null, Action.CREATE);
    SecureTestUtil.grantOnTable(TEST_UTIL, tableAdmin.getShortName(), testTable.getTableName(),
      null, null, Action.ADMIN);

    grantGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.WRITE);
    try {
      // Write tests

      AccessTestAction writeAction = new AccessTestAction() {
        @Override
        public Object run() throws Exception {

          try (Connection conn = ConnectionFactory.createConnection(conf);
            Table t = conn.getTable(PermissionStorage.ACL_TABLE_NAME)) {
            t.put(new Put(TEST_ROW).addColumn(PermissionStorage.ACL_LIST_FAMILY, TEST_QUALIFIER,
              TEST_VALUE));
            return null;
          } finally {
          }
        }
      };

      // All writes to ACL table denied except for GLOBAL WRITE permission and superuser

      verifyDenied(writeAction, globalAdmin, globalCreate, globalRead, TESTGROUP2_USER1);
      verifyDenied(writeAction, nsAdmin, nsCreate, nsRead, nsWrite);
      verifyDenied(writeAction, tableAdmin, tableCreate, tableRead, tableWrite);
      verifyAllowed(writeAction, superUser, globalWrite, TESTGROUP1_USER1);
    } finally {
      revokeGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.WRITE);
    }

    grantGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.READ);
    try {
      // Read tests

      AccessTestAction scanAction = new AccessTestAction() {
        @Override
        public Object run() throws Exception {
          try (Connection conn = ConnectionFactory.createConnection(conf);
            Table t = conn.getTable(PermissionStorage.ACL_TABLE_NAME)) {
            ResultScanner s = t.getScanner(new Scan());
            try {
              for (Result r = s.next(); r != null; r = s.next()) {
                // do nothing
              }
            } finally {
              s.close();
            }
            return null;
          }
        }
      };

      // All reads from ACL table denied except for GLOBAL READ and superuser

      verifyDenied(scanAction, globalAdmin, globalCreate, globalWrite, TESTGROUP2_USER1);
      verifyDenied(scanAction, nsCreate, nsAdmin, nsRead, nsWrite);
      verifyDenied(scanAction, tableCreate, tableAdmin, tableRead, tableWrite);
      verifyAllowed(scanAction, superUser, globalRead, TESTGROUP1_USER1);
    } finally {
      revokeGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.READ);
    }
  }
The systemUserConnection created here is tied to the system user. In case, you are planning to
create AccessTestAction, DON'T use this systemUserConnection as the 'doAs' user gets eclipsed
by the system user.
hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController2.java