

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

# 通过 Gremlin Java 使用 IAM 连接到 Amazon Neptune 数据库
<a name="iam-auth-connecting-gremlin-java"></a>

以下是如何使用带有 Sig4 签名的 Gremlin Java API 连接到 Neptune 的示例（它假设对使用 Maven 有常识）。此示例使用 [Amazon Neptune SigV4 Signer](https://github.com/aws/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，其中`DefaultCredentialsProvider`为`software.amazon.awssdk.auth.credentials.AwsCredentialsProvider`实例。如果您要从 1.x 升级到 2.x，请参阅适用于 Java 的 AWS SDK 2.x 文档中的[凭证提供程序更改](https://docs.aws.amazon.com//sdk-for-java/latest/developer-guide/migration-client-credentials.html)。

```
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 身份验证
<a name="iam-auth-connecting-gremlin-java-cross-account"></a>

 Amazon Neptune 支持通过使用角色代入（有时也称为[角色链](https://docs.aws.amazon.com//neptune/latest/userguide/bulk-load-tutorial-chain-roles.html#bulk-load-tutorial-chain-cross-account)）来进行跨账户 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](https://docs.aws.amazon.com//sdk-for-java/v1/developer-guide/credentials.html)时通过`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();
    }
  ```