Использование ACL с куратором

Используя CuratorFramework, кто-нибудь может объяснить, как я могу:

  1. Создать новый путь
  2. Установить данные для этого пути
  3. Получить этот путь

Используя имя пользователя foo и пароль bar? Те, кто не знает этого пользователя /pass, не смогут ничего сделать.

Меня не волнует SSL или пароли, отправляемые через открытый текст для целей этого вопроса.

1 ответ

Решение

ACL в Apache Curator предназначены для контроля доступа. Поэтому ZooKeeper не предоставляет какой-либо механизм аутентификации, такой как, clients who don't have correct password cannot connect to ZooKeeper or cannot create ZNodes, Он может предотвратить доступ неавторизованных клиентов к определенным Znode/ZNodes. Для этого вам необходимо настроить экземпляр CuratorFramework, как я описал ниже. Помните, это будет гарантировать, что ZNode, созданный с заданным ACL, может снова получить доступ к тому же клиенту или клиенту, представляющему ту же информацию аутентификации.

Сначала вы должны построить CuratorFramework мгновенно следующим образом. Здесь connectString означает разделенный запятыми список ip and port комбинации серверов zookeeper в вашем ансамбле.

CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
                .connectString(connectString)
                .retryPolicy(new ExponentialBackoffRetry(retryInitialWaitMs, maxRetryCount))
                .connectionTimeoutMs(connectionTimeoutMs)
                .sessionTimeoutMs(sessionTimeoutMs);
    /*
     * If authorization information is available, those will be added to the client. NOTE: These auth info are
     * for access control, therefore no authentication will happen when the client is being started. These
     * info will only be required whenever a client is accessing an already create ZNode. For another client of
     * another node to make use of a ZNode created by this node, it should also provide the same auth info.
     */
    if (zkUsername != null && zkPassword != null) {
        String authenticationString = zkUsername + ":" + zkPassword;
        builder.authorization("digest", authenticationString.getBytes())
                .aclProvider(new ACLProvider() {
                    @Override
                    public List<ACL> getDefaultAcl() {
                        return ZooDefs.Ids.CREATOR_ALL_ACL;
                    }

                    @Override
                    public List<ACL> getAclForPath(String path) {
                        return ZooDefs.Ids.CREATOR_ALL_ACL;
                    }
                });
    }

CuratorFramework client = builder.build();

Теперь вы должны начать это.

client.start();

Создание пути.

client.create().withMode(CreateMode.PERSISTENT).forPath("/your/ZNode/path");

Здесь CreateMode укажите, какой тип узла вы хотите создать. Доступные типы PERSISTENT,EPHEMERAL,EPHEMERAL_SEQUENTIAL,PERSISTENT_SEQUENTIAL,CONTAINER, Документы Java

Если вы не уверены, что путь до /your/ZNode уже существует, вы также можете создавать их.

client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/your/ZNode/path");

Установить данные

Вы можете установить данные либо при создании ZNode, либо позже. Если вы устанавливаете данные во время создания, передайте данные как byte массив как второй параметр forPath() метод.

client.create().withMode(CreateMode.PERSISTENT).forPath("/your/ZNode/path","your data as String".getBytes());

Если вы делаете это позже, (данные должны быть представлены в виде байтового массива)

client.setData().forPath("/your/ZNode/path",data);

в заключение

Я не понимаю, что вы подразумеваете под get this path, Apache Curator это Java-клиент (более того, с рецептами куратора), который использует Apache Zookeeper на заднем плане скрываются крайние случаи и сложности Zookeeper. В Zookeeper они используют концепцию ZNodes хранить данные. Вы можете рассматривать это как структуру каталогов Linux. Все ZNodePaths должен начинаться с / (root), и вы можете продолжать указывать каталог, такой как ZNodePaths, как вам нравится. Пример: /someName/another/test/sample,

Структура ZNode

Как показано на приведенной выше диаграмме, ZNode организованы в виде древовидной структуры. каждый ZNode может хранить до 1 МБ данных. Следовательно, если вы хотите получить данные, хранящиеся в ZNode, вам нужно знать путь к этому ZNode. (Точно так же, как вы должны знать таблицу и столбец базы данных, чтобы получить данные).

Если вы хотите получить данные по заданному пути,

client.getData().forPath("/path/to/ZNode");

Это все, что вам нужно знать, когда вы хотите работать с куратором.

Еще кое-что

ACL в Apache Curator предназначены для контроля доступа. То есть, если вы установите ACLProvider следующее,

new ACLProvider() {
    @Override
    public List<ACL> getDefaultAcl () {
        return ZooDefs.Ids.CREATOR_ALL_ACL;
    }

    @Override
    public List<ACL> getAclForPath (String path){
        return ZooDefs.Ids.CREATOR_ALL_ACL;
    }
}

только клиенту с учетными данными, идентичными создателю, будет предоставлен доступ к соответствующему ZNode позже. Детали аутентификации устанавливаются следующим образом (см. Пример построения клиента). Доступны и другие режимы ACL, такие как OPEN_ACL_UNSAFE которые не делают никакого контроля доступа, если вы установите его как ACLProvider.

authorization("digest", authorizationString.getBytes())

позже они будут использоваться для управления доступом к данному ZNode.

Короче говоря, если вы хотите, чтобы другие не вмешивались в ваши ZNodes, вы можете настроить ACLProvider на возврат CREATOR_ALL_ACL и установите разрешение на digest как показано выше. Только экземпляры CuratorFramework, использующие одну и ту же строку авторизации ("username:password") сможет получить доступ к этим ZNodes. Но это не помешает другим создавать ZNodes в путях, которые не мешают вашему.

Надеюсь, вы нашли то, что вы хотите:-)

Это не было частью первоначального вопроса, но я подумал, что поделюсь решением, которое придумал, в котором использованные учетные данные определяют уровень доступа.

Мне не повезло найти примеры, и я продолжал попадать на эту страницу, так что, возможно, это поможет кому-то еще. Я копался в исходном коде Curator Framework и, к счастью, класс org.apache.curator.framework.recipes.leader.TestLeaderAcls был там, чтобы указать мне правильное направление.

Итак, в этом примере:

  1. Один универсальный клиент, используемый в нескольких приложениях, который должен только читать данные из ZK.
  2. Другой клиент администратора имеет возможность читать, удалять и обновлять узлы в ZK.
  3. Доступ только для чтения или доступ администратора определяется используемыми учетными данными.

ПОЛНЫЙ КОНТРОЛЬ АДМИН КЛИЕНТ

    import java.security.NoSuchAlgorithmException;
    import java.util.ArrayList;
    import java.util.List;
    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.ACLProvider;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.ZooDefs;
    import org.apache.zookeeper.data.ACL;
    import org.apache.zookeeper.data.Id;
    import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;

    public class AdminClient {

        protected static CuratorFramework client = null;

        public void initializeClient() throws NoSuchAlgorithmException {
            String zkConnectString = "127.0.0.1:2181";
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
            final List<ACL> acls = new ArrayList<>();

            //full-control ACL
            String zkUsername = "adminuser";
            String zkPassword = "adminpass";
            String fullControlAuth = zkUsername + ":" + zkPassword;
            String fullControlDigest = DigestAuthenticationProvider.generateDigest(fullControlAuth);
            ACL fullControlAcl = new ACL(ZooDefs.Perms.ALL, new Id("digest", fullControlDigest));
            acls.add(fullControlAcl);

            //read-only ACL
            String zkReadOnlyUsername = "readuser";
            String zkReadOnlyPassword = "readpass";
            String readOnlyAuth = zkReadOnlyUsername + ":" + zkReadOnlyPassword;
            String readOnlyDigest = DigestAuthenticationProvider.generateDigest(readOnlyAuth);
            ACL readOnlyAcl = new ACL(ZooDefs.Perms.READ, new Id("digest", readOnlyDigest));
            acls.add(readOnlyAcl);

            //create the client with full-control access
            client = CuratorFrameworkFactory.builder()
                .connectString(zkConnectString)
                .retryPolicy(retryPolicy)
                .authorization("digest", fullControlAuth.getBytes())
                .aclProvider(new ACLProvider() {
                    @Override
                    public List<ACL> getDefaultAcl() {
                        return acls;
                    }

                    @Override
                    public List<ACL> getAclForPath(String string) {
                        return acls;
                    }
                })
                .build();
            client.start();
            //Now create, read, delete ZK nodes
        }
    }

ЧИТАЙТЕ ТОЛЬКО КЛИЕНТА

    import java.security.NoSuchAlgorithmException;
    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.retry.ExponentialBackoffRetry;

    public class ReadOnlyClient {

        protected static CuratorFramework client = null;

        public void initializeClient() throws NoSuchAlgorithmException {
            String zkConnectString = "127.0.0.1:2181";
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
            String zkReadOnlyUsername = "readuser";
            String zkReadOnlyPassword = "readpass";
            String readOnlyAuth = zkReadOnlyUsername + ":" + zkReadOnlyPassword;
            client = CuratorFrameworkFactory.builder()
                    .connectString(zkConnectString)
                    .retryPolicy(retryPolicy)
                    .authorization("digest", readOnlyAuth.getBytes())
                    .build();
            client.start();
            //Now read ZK nodes
        }
    }
Другие вопросы по тегам