Использование ACL с куратором
Используя CuratorFramework, кто-нибудь может объяснить, как я могу:
- Создать новый путь
- Установить данные для этого пути
- Получить этот путь
Используя имя пользователя 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
может хранить до 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 был там, чтобы указать мне правильное направление.
Итак, в этом примере:
- Один универсальный клиент, используемый в нескольких приложениях, который должен только читать данные из ZK.
- Другой клиент администратора имеет возможность читать, удалять и обновлять узлы в ZK.
- Доступ только для чтения или доступ администратора определяется используемыми учетными данными.
ПОЛНЫЙ КОНТРОЛЬ АДМИН КЛИЕНТ
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
}
}