

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

# 使用适用于 Rust 的 AWS SDK 创建预签名 URL
<a name="presigned-urls"></a>

 您可以对某些 AWS API 操作的请求进行预签名，以便其他调用方以后无需提供自己的凭证即可使用该请求。

 例如，假设 Jane 有权访问 Amazon Simple Storage Service（Amazon S3）对象，并希望临时与 Alejandro 分享对该对象的访问权限。Jane 可以生成预签名的 `GetObject` 请求来分享给 Alejandro，这样 Alejandro 就可以下载该对象而无需访问 Jane 的凭证，也无需拥有自己的凭证。预签名 URL 使用的凭证是 Jane 的，因为她是生成该 URL 的 AWS 用户。

要了解有关 Amazon S3 中预签名 URL 的更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[使用预签名 URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html)。

## 预签名基础知识
<a name="presign-basics"></a>

 适用于 Rust 的 AWS SDK 在操作 fluent-builders 上提供了一个 `presigned()` 方法，可用于获取预签名请求。

 以下示例展示了为 Amazon S3 创建预签名 `GetObject` 请求的过程。请求在创建后的 5 分钟内有效。

```
use std::time::Duration;
use aws_config::BehaviorVersion;
use aws_sdk_s3::presigning::PresigningConfig;

let config = aws_config::defaults(BehaviorVersion::latest())
    .load()
    .await;

let s3 = aws_sdk_s3::Client::new(&config);

let presigned = s3.get_object()
    .presigned(
        PresigningConfig::builder()
            .expires_in(Duration::from_secs(60 * 5))
            .build()
            .expect("less than one week")
    )
    .await?;
```

 `presigned()` 方法返回 `Result<PresignedRequest, SdkError<E, R>>`。

返回的 `PresignedRequest` 包含用于获取 HTTP 请求组件的方法，包括方法、URI 和任何标头。所有这些都需要发送到相应服务（如果有），请求才会生效。不过，许多预签名请求可以单独由 URI 表示。

## 预签名 `POST` 和 `PUT` 请求
<a name="presign-post-put"></a>

 许多可预签名的操作只需要一个 URL，并且必须作为 HTTP `GET` 请求发送。但是，有些操作需要正文，在某些情况下必须作为 HTTP `POST` 或 HTTP `PUT` 请求与标头一起发送。对这些请求进行预签名与对 `GET` 请求进行预签名相同，但是调用预签名请求更为复杂。

 以下示例展示了对 Amazon S3 `PutObject` 请求进行预签名并将其转换为可使用所选 HTTP 客户端发送的 [https://docs.rs/http/latest/http/request/struct.Request.html](https://docs.rs/http/latest/http/request/struct.Request.html) 请求的过程。

要使用 `into_http_1x_request()` 方法，请将 `http-1x` 功能添加到 `Cargo.toml` 文件中的 `aws-sdk-s3` crate。

```
aws-sdk-s3 = { version = "1", features = ["http-1x"] }
```

源文件：

```
let presigned = s3.put_object()
    .presigned(
        PresigningConfig::builder()
            .expires_in(Duration::from_secs(60 * 5))
            .build()
            .expect("less than one week")
    )
    .await?;


let body = "Hello AWS SDK for Rust";
let http_req = presigned.into_http_1x_request(body);
```

## 独立签署人
<a name="standalone-signer"></a>

**注意**  
这是一个高级使用案例。对于大多数用户来说，既不需要也不建议使用。

在一些使用案例中，需要在适用于 Rust 的 SDK 上下文之外创建签名请求。为此，您可以独立于 SDK 使用 [https://docs.rs/aws-sigv4/latest/aws_sigv4/index.html](https://docs.rs/aws-sigv4/latest/aws_sigv4/index.html) crate。

 以下示例展示了基本元素。有关更多详细信息，请参阅 crate 文档。

将 `aws-sigv4` 和 `http` crate 添加到 `Cargo.toml` 文件中：

```
[dependencies]
aws-sigv4 = "1"
http = "1"
```

源文件：

```
use aws_smithy_runtime_api::client::identity::Identity;
use aws_sigv4::http_request::{sign, SigningSettings, SigningParams, SignableRequest};
use aws_sigv4::sign::v4;
use std::time::SystemTime;

// Set up information and settings for the signing.
// You can obtain credentials from `SdkConfig`.
let identity = Credentials::new(
    "AKIDEXAMPLE",
    "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
    None,
    None,
    "hardcoded-credentials").into();

let settings = SigningSettings::default();

let params = v4::SigningParams::builder()
    .identity(&identity)
    .region("us-east-1")
    .name("service")
    .time(SystemTime::now())
    .settings(settings)
    .build()?
    .into();

// Convert the HTTP request into a signable request.
let signable = SignableRequest::new(
    "GET",
    "https://some-endpoint.some-region.amazonaws.com",
    std::iter::empty(),
    SignableBody::UnsignedPayload
)?;

// Sign and then apply the signature to the request.
let (signing_instructions, _signature) = sign(signable, &params)?.into_parts();

let mut my_req = http::Request::new("...");
signing_instructions.apply_to_request_http1x(&mut my_req);
```