Conexión a bases de datos de Amazon Neptune mediante IAM con Java de Gremlin - Amazon Neptune

Conexión a bases de datos de Amazon Neptune mediante IAM con Java de Gremlin

Uso de TinkerPop 3.4.11 o posterior para conectarse a Neptune con la firma Sig4

A continuación, se ofrece un ejemplo de cómo conectarse a Neptune usando la API de Java de Gremlin con firma Sig4 cuando se usa TinkerPop 3.4.11 o posterior (se supone que se tienen conocimientos generales sobre el uso de Maven). En este ejemplo, se utiliza la biblioteca Amazon Neptune SigV4 Signer para facilitar la firma de solicitudes. Primero, defina las dependencias como parte del archivo pom.xml:

nota

Los siguientes ejemplos se han actualizado para incluir el uso de requestInterceptor(). Esto se agregó en TinkerPop 3.6.6. Antes de la versión 3.6.6 de TinkerPop, los ejemplos de código utilizaban handshakeInterceptor(), que quedó obsoleto con esa versión.

<dependency> <groupId>com.amazonaws</groupId> <artifactId>amazon-neptune-sigv4-signer</artifactId> <version>3.1.0</version> </dependency>

Amazon Neptune SigV4 Signer admite el uso de las versiones 1.x y 2.x del AWS SDK para Java. En el siguiente ejemplo, se utiliza la versión 2.x, en la que DefaultCredentialsProvider es una software.amazon.awssdk.auth.credentials.AwsCredentialsProvider instancia, pero también se podría utilizar la versión 1.x con cualquier com.amazonaws.auth.AWSCredentialsProvider. Si va a actualizar de la versión 1.x a la 2.x, puede obtener más información sobre los cambios entre ambas versiones en Cambios en el proveedor de credenciales de la documentación del AWS SDK para Java 2.x.

import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.neptune.auth.NeptuneNettyHttpSigV4Signer; import com.amazonaws.neptune.auth.NeptuneSigV4SignerException; ... System.setProperty("aws.accessKeyId","your-access-key"); System.setProperty("aws.secretKey","your-secret-key"); ... Cluster cluster = Cluster.build((your cluster)) .enableSsl(true) .requestInterceptor( r -> { try { NeptuneNettyHttpSigV4Signer sigV4Signer = new NeptuneNettyHttpSigV4Signer("(your region)", DefaultCredentialsProvider.create()); sigV4Signer.signRequest(r); } catch (NeptuneSigV4SignerException e) { throw new RuntimeException("Exception occurred while signing the request", e); } return r; } ).create(); try { Client client = cluster.connect(); client.submit("g.V().has('code','IAD')").all().get(); } catch (Exception e) { throw new RuntimeException("Exception occurred while connecting to cluster", e); }
nota

Si está actualizando desde 3.4.11, elimine las referencias a la biblioteca de amazon-neptune-gremlin-java-sigv4. Ya no es necesario cuando se utiliza requestInterceptor() como se muestra en el ejemplo anterior. No intente utilizarla requestInterceptor() junto con el canalizador (SigV4WebSocketChannelizer.class), ya que se producirán errores.

Autenticación de IAM entre cuentas

Amazon Neptune admite la autenticación de IAM entre cuentas mediante el uso de la asunción de roles, también conocida como encadenamiento de roles. Para proporcionar acceso a un clúster de Neptune desde una aplicación alojada en una cuenta de AWS diferente:

  • Cree un nuevo usuario o rol de IAM en la cuenta de AWS de la aplicación, con una política de confianza que permita al usuario o rol asumir otro rol de IAM. Asigne este rol al servicio de computación que aloja la aplicación (instancia EC2, función de Lambda, tarea de ECS, etc.).

  • Cree un nuevo rol de IAM en la cuenta de AWS de la base de datos de Neptune que permita el acceso a la base de datos de Neptune y permita la asunción de roles desde el usuario/rol de IAM de la cuenta de aplicación. Utilice una política de confianza de:

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "(ARN of application account IAM user or role)" ] }, "Action": "sts:AssumeRole", "Condition": {} } ] }
  • Utilice el siguiente ejemplo de código como guía para utilizar estos dos roles y permitir que la aplicación acceda a Neptune. En este ejemplo, el rol de la cuenta de la aplicación se asumirá mediante DefaultCredentialProviderChain al crear STSclient. A continuación, STSclient se utiliza a través de STSAssumeRoleSessionCredentialsProvider para asumir el rol alojado en la cuenta de AWS de la base de datos de Neptune.

    public static void main( String[] args ) { /* * Establish an STS client from the application account. */ AWSSecurityTokenService client = AWSSecurityTokenServiceClientBuilder .standard() .build(); /* * Define the role ARN that you will be assuming in the database account where the Neptune cluster resides. */ String roleArnToAssume = "arn:aws:iam::012345678901:role/CrossAccountNeptuneRole"; String crossAccountSessionName = "cross-account-session-" + UUID.randomUUID(); /* * Change the Credentials Provider in the SigV4 Signer to use the STSAssumeRole Provider and provide it * with both the role to be assumed, the original STS client, and a session name (which can be * arbitrary.) */ Cluster cluster = Cluster.build() .addContactPoint("neptune-cluster.us-west-2.neptune.amazonaws.com") .enableSsl(true) .port(8182) .requestInterceptor( r -> { try { NeptuneNettyHttpSigV4Signer sigV4Signer = // new NeptuneNettyHttpSigV4Signer("us-west-2", new DefaultAWSCredentialsProviderChain()); new NeptuneNettyHttpSigV4Signer( "us-west-2", new STSAssumeRoleSessionCredentialsProvider .Builder(roleArnToAssume, crossAccountSessionName) .withStsClient(client) .build()); sigV4Signer.signRequest(r); } catch (NeptuneSigV4SignerException e) { throw new RuntimeException("Exception occurred while signing the request", e); } return r; } ).create(); GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster)); /* whatever application code is necessary */ cluster.close(); }

Uso de una versión de TinkerPop anterior a la 3.4.11 para conectarse a Neptune con la firma Sig4

Las versiones de TinkerPop anteriores a la 3.4.11 no eran compatibles con la configuración de requestInterceptor() que se muestra en la sección anterior y, por lo tanto, deben confiar en el paquete amazon-neptune-gremlin-java-sigv4. Esta es una biblioteca de Neptune que contiene la clase SigV4WebSocketChannelizer, que reemplaza al canalizador de TinkerPop estándar por uno que puede inyectar automáticamente una firma SigV4. Siempre que sea posible, actualice a TinkerPop 3.4.11 o una versión posterior, ya que la biblioteca amazon-neptune-gremlin-java-sigv4 está en desuso.

A continuación, se ofrece un ejemplo de cómo conectarse a Neptune mediante la API de Java de Gremlin con firma Sig4 cuando se utilizan versiones de TinkerPop anteriores a la 3.4.11 (se supone que se tienen conocimientos generales sobre cómo usar Maven).

Primero, defina las dependencias como parte del archivo pom.xml:

<dependency> <groupId>com.amazonaws</groupId> <artifactId>amazon-neptune-gremlin-java-sigv4</artifactId> <version>2.4.0</version> </dependency>

La dependencia anterior incluirá la versión del controlador de Gremlin 3.4.10. Aunque es posible utilizar versiones más recientes del controlador de Gremlin (hasta la 3.4.13), la actualización del controlador a partir de la versión 3.4.10 debería incluir un cambio para utilizar el modelo de requestInterceptor() descrito anteriormente.

A continuación, el objeto de clúster gremlin-driver debe configurarse de la siguiente manera en el código Java:

import org.apache.tinkerpop.gremlin.driver.SigV4WebSocketChannelizer; ... Cluster cluster = Cluster.build(your cluster) .enableSsl(true) .channelizer(SigV4WebSocketChannelizer.class) .create(); Client client = cluster.connect(); client.submit("g.V().has('code','IAD')").all().get();