通过 Gremlin Java 使用 IAM 连接到 Amazon Neptune 数据库 - Amazon Neptune
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

通过 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 版本。 Amazon 以下示例使用 2.x,其中DefaultCredentialsProvidersoftware.amazon.awssdk.auth.credentials.AwsCredentialsProvider实例。如果您要从 1.x 升级到 2.x,请参阅适用于 Java 的 Amazon 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 身份验证。要提供从托管在不同 Amazon 账户中的应用程序访问 Neptune 集群的权限,请执行以下操作:

  • 在应用程序 Amazon 账户中创建新的 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 数据库 Amazon 账户中创建一个新的 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 数据库 Amazon 账户中托管的角色。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(); }