通过 Gremlin Java 使用 IAM 连接到 Amazon Neptune 数据库 - Amazon Neptune

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

通过 Gremlin Java 使用 IAM 连接到 Amazon Neptune 数据库

以下是如何使用带有 Sig4 签名的 Gremlin Java API 连接到 Neptune 的示例(它假设对使用 Maven 有常识)。此示例使用 Amazon Neptune SigV4 Signer 库来协助请求签名。首先,将依赖关系定义为 pom.xml 文件的一部分:

注意

以下示例使用requestInterceptor()了 TinkerPop 3.6.6 中引入的。如果您使用的是早于 3.6.6 的 TinkerPop 版本(但是 3.5.5 或更高版本),请在下面的代码示例requestInterceptor()中使用handshakeInterceptor()代替。

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

亚马逊 Neptune Sigv4 Signer 支持 Java SDK 的 1.x 和 2.x 版本。 AWS 以下示例使用 2.x,其中DefaultCredentialsProvidersoftware.amazon.awssdk.auth.credentials.AwsCredentialsProvider实例。如果您要从 1.x 升级到 2.x,请参阅适用于 Java 的 AWS SDK 2.x 文档中的凭证提供程序更改

import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; 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); }

跨账户 IAM 身份验证

Amazon Neptune 支持通过使用角色代入(有时也称为角色链)来进行跨账户 IAM 身份验证。要提供从托管在不同 AWS 账户中的应用程序访问 Neptune 集群的权限,请执行以下操作:

  • 在应用程序 AWS 账户中创建新的 IAM 用户或角色,其信任策略允许该用户或角色担任另一个 IAM 角色。将该角色分配给托管应用程序(EC2 实例、Lambda 函数、ECS 任务等)的计算。

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Sid": "assumeRolePolicy", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::111122223333:role/role-name" } ] }
  • 在 Neptune 数据库 AWS 账户中创建一个新的 IAM 角色,该角色允许访问 Neptune 数据库,并允许从应用程序账户 IAM 用户/角色担任角色。使用以下信任策略:

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "(ARN of application account IAM user or role)" ] }, "Action": "sts:AssumeRole", "Condition": {} } ] }
  • 使用以下代码示例作为指导,了解如何使用这两个角色来允许应用程序访问 Neptune。在此示例中,应用程序账户角色将在创建DefaultCredentialProviderChain时通过STSclient。然后通过使用STSAssumeRoleSessionCredentialsProvider来代替 Neptune 数据库 AWS 账户中托管的角色。STSclient

    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", DefaultCredentialsProvider.create()); 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(); }