java - Usando ACL con Curador
apache-zookeeper apache-curator (2)
ACL en Apache Curator son para control de acceso. Por lo tanto, ZooKeeper no proporciona ningún mecanismo de autenticación, los clients who don''t have correct password cannot connect to ZooKeeper or cannot create ZNodes
. Lo que puede hacer es evitar que clientes no autorizados accedan a determinados Znode / ZNodes. Para hacer eso, debe configurar la instancia de CuratorFramework como se describe a continuación. Recuerde, esto garantizará que, el mismo cliente o un cliente que presente la misma información de autenticación puedan acceder nuevamente a un ZNode creado con una ACL determinada.
En primer lugar, debe crear la CuratorFramework
CuratorFramework de la siguiente manera. Aquí, connectString
significa una lista separada por comas de ip and port
combinaciones de ip and port
de los servidores zookeeper en su conjunto.
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();
Ahora tienes que empezar.
client.start();
Creando un camino.
client.create().withMode(CreateMode.PERSISTENT).forPath("/your/ZNode/path");
Aquí, el CreateMode
especifica qué tipo de nodo desea crear. Los tipos disponibles son PERSISTENT,EPHEMERAL,EPHEMERAL_SEQUENTIAL,PERSISTENT_SEQUENTIAL,CONTAINER
. Documentos de Java
Si no está seguro de si ya existe la ruta hasta /your/ZNode
, también puede crearlos.
client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/your/ZNode/path");
Establecer datos
Puede configurar los datos cuando esté creando el ZNode o posterior. Si está configurando datos en el momento de la creación, pase los datos como una matriz de byte
como segundo parámetro al método forPath()
.
client.create().withMode(CreateMode.PERSISTENT).forPath("/your/ZNode/path","your data as String".getBytes());
Si lo hace más adelante, (los datos deben proporcionarse como una matriz de bytes)
client.setData().forPath("/your/ZNode/path",data);
Finalmente
No entiendo lo que quieres decir con get this path
. Apache Curator
es un cliente java (más que eso con Curator Recipes) que utiliza Apache Zookeeper
en segundo plano y oculta los casos y las complejidades de Zookeeper. En Zookeeper, utilizan el concepto de ZNodes
para almacenar datos. Puedes considerarlo como la estructura de directorios de Linux. Todas las ZNodePaths
deben comenzar con /
(raíz) y puede continuar especificando el directorio como ZNodePaths como desee. Ej: /someName/another/test/sample
.
Como se muestra en el diagrama anterior, los ZNodos están organizados en una estructura de árbol. Cada ZNode
puede almacenar hasta 1MB de datos. Por lo tanto, si desea recuperar datos almacenados en un ZNode, necesita conocer la ruta a ese ZNode. (Al igual que usted debe saber la tabla y la columna de una base de datos para recuperar datos).
Si desea recuperar datos en una ruta determinada,
client.getData().forPath("/path/to/ZNode");
Eso es todo lo que tienes que saber cuando quieres trabajar con Curator.
Una cosa más
ACL en Apache Curator son para control de acceso. Es decir, si establece ACLProvider
como sigue,
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;
}
}
solo el cliente con las credenciales idénticas al creador tendrá acceso al ZNode correspondiente más adelante. Los detalles de la automatización se establecen de la siguiente manera (consulte el ejemplo de construcción del cliente). Hay otros modos de ACL disponibles, como OPEN_ACL_UNSAFE
que no hacen ningún control de acceso si lo configura como ACLProvider.
authorization("digest", authorizationString.getBytes())
se utilizarán más adelante para controlar el acceso a un ZNode dado.
En resumen, si desea evitar que otras personas interfieran con sus ZNodes, puede configurar el proveedor de ACL para que devuelva CREATOR_ALL_ACL
y configurar la autorización para digest
como se muestra arriba. Solo las instancias de CuratorFramework que utilicen la misma cadena de autorización ( "username:password"
) podrán acceder a esos ZNodes. Pero no evitará que otros creen ZNodes en rutas que no interfieran con las suyas.
Espero que hayas encontrado lo que quieres :-)
Usando CuratorFramework , ¿podría alguien explicar cómo puedo:
- Crear un nuevo camino
- Establecer datos para esta ruta
- Consigue este camino
Usando el nombre de usuario foo
y la bar
contraseñas? Aquellos que no conocen este usuario / pase no podrían hacer nada.
No me importa si SSL o las contraseñas se envían a través de texto sin formato para el propósito de esta pregunta.
No formaba parte de la pregunta original, pero pensé que compartiría una solución que se me ocurrió en la que las credenciales utilizadas determinan el nivel de acceso.
No tuve mucha suerte en encontrar ejemplos y seguí terminando en esta página, así que quizás ayude a alguien más. Revisé el código fuente de Curator Framework y, por suerte, la clase org.apache.curator.framework.recipes.leader.TestLeaderAcls estaba allí para apuntarme en la dirección correcta.
Así que en este ejemplo:
- Un cliente genérico utilizado en múltiples aplicaciones que solo necesita leer datos de ZK.
- Otro cliente de administración tiene la capacidad de leer, eliminar y actualizar nodos en ZK.
- El acceso de solo lectura o de administrador está determinado por las credenciales utilizadas.
CLIENTE DE CONTROL COMPLETO
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
}
}
CLIENTE DE LEER SOLO
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
}
}