このトピックでは、Security Token Service (STS) の署名付きURLまたは一時的なアクセス資格情報を使用して、オブジェクトをObject Storage Service (OSS) に直接アップロードする権限をサードパーティのユーザーに付与する方法について説明します。
背景情報
標準のクライアント /サーバーシステムアーキテクチャでは、サーバーはクライアントからのリクエストの受信と処理を担当し、OSSはバックエンドストレージサービスとして使用されます。 その場合、クライアントはアップロードするオブジェクトをアプリケーションサーバーに送信します。 次に、サーバーはオブジェクトをOSSに転送します。 このプロセスでは、オブジェクトはクライアントからサーバーに、サーバーからOSSに2回送信されます。 アクセスリクエストが急増している場合、サーバーは十分な帯域幅リソースを提供して、複数のクライアントがオブジェクトを同時にアップロードできるようにする必要があります。 これは、アーキテクチャのスケーラビリティに対する課題です。
メリット
上記のシナリオでの課題に対処するために、OSSではサードパーティのアップロードを承認できます。 これにより、各クライアントはオブジェクトをサーバーに送信せずにOSSに直接アップロードできます。 これにより、アプリケーションサーバーのコストが削減され、大量のデータを処理するOSS機能が最大化されます。 さらに、帯域幅と同時実行制限について心配することなく、ビジネスに集中できます。 署名付きURLまたは一時的なアクセス資格情報を使用して、サードパーティのユーザーにオブジェクトをOSSに直接アップロードする権限を付与するオプションがあります。 ほとんどの場合、一時的なアクセス資格情報を使用することを推奨します。
一時的なアクセス資格情報を使用して、サードパーティユーザーにOSSへのオブジェクトのアップロードを許可する
ほとんどのオブジェクトアップロードのシナリオでは、Security Token Service (STS) SDKを使用してアプリケーションサーバーの一時的なアクセス資格情報を取得し、一時的なアクセス資格情報とOSS SDKを使用してクライアントからOSSに直接オブジェクトをアップロードすることを推奨します。 クライアントは、アプリケーションサーバ上の一時的なアクセス資格情報を再利用して署名を生成することができる。 これは、マルチパートアップロードと再開可能アップロードを使用してラージオブジェクトをアップロードするシナリオに適しています。 ただし、STSへの頻繁な呼び出しにより、スロットリングが発生する場合があります。 この場合、一時的なアクセス資格情報をキャッシュし、有効期間が終了する前に更新することを推奨します。 詳細については、「STSの概要」をご参照ください。
一時的なアクセス資格情報を取得します。
一時的なアクセス資格情報は、AccessKeyペアとセキュリティトークンで構成されます。 AccessKeyペアは、AccessKey IDとAccessKeyシークレットで構成されます。 一時的なアクセス資格情報の最小有効期間は900秒です。 一時的なアクセス資格情報の最大有効期間は、現在のロールに指定されている最大セッション期間です。 詳細については、「RAMロールの最大セッション期間の指定」をご参照ください。
次のいずれかの方法を使用して、一時的なアクセス資格情報を取得できます。
一時的なアクセス資格情報を使用して、サードパーティユーザーにオブジェクトのアップロードを許可します。
次のサンプルコードは、一時的なアクセス資格情報を使用して、一般的なプログラミング言語のOSS SDKを使用して、サードパーティユーザーにオブジェクトをOSSにアップロードする権限を付与する方法の例を示しています。 他のプログラミング言語でOSS SDKを使用してこの操作を実行する方法の詳細については、「概要」をご参照ください。
Java
com.aliyun.oss.*;
com.aliyun.oss.mo del.PutObjectRequestをインポートします。impor t com.aliyun.oss.com mon.auth.*;
java.io. ファイルをインポートします。public classデモ {
public static void main(String[] args) Throwable {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET、およびOSS_SESSION_TOKEN環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// バケットの名前を指定します。 例: examplebucket.
String bucketName = "examplebucket";
// オブジェクトのフルパスを指定します。 例: exampleobject.txt。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
// ローカルファイルのフルパスを指定します。
文字列pathName = "D :\\ examplefile.txt";
// Create an OSSClient instance.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// ローカルファイルのフルパスを指定します。 デフォルトでは、ローカルファイルのフルパスを指定しない場合、サンプルプログラムが属するプロジェクトのパスからローカルファイルがアップロードされます。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(pathName));
ossClient.putObject(putObjectRequest);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "しかし、何らかの理由でエラー応答で拒否されました。");
System.out.println("エラーメッセージ:" + oe.getErrorMessage());
System.out.println("エラーコード:" + oe.getErrorCode());
System.out.println("リクエストID:" + oe.getRequestId());
System.out.println("ホストID:" + oe.getHostId());
} catch (ClientException e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
PHP
<?php
if (is_file(__DIR__) 。 '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__) 。 '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
OSS\OssClientを使用します。OSS\Core\OssExceptionを使用します。// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET、およびOSS_SESSION_TOKEN環境変数が設定されていることを確認してください。
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
$securityToken = getenv("OSS_SESSION_TOKEN");
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。
$end point = "yourEndpoint";
// バケットの名前を指定します。
$bucket= "examplebucket";
// オブジェクトのフルパスを指定します。 オブジェクトのフルパスにバケット名を含めないでください。
$object = "exampleobject.txt";
// オブジェクトとしてアップロードする文字列を指定します。
$content = "Hello OSS";
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken);
// STSから取得した一時的なアクセス資格情報を使用して、オブジェクトに文字列をアップロードします。
$ossClient->putObject($bucket、$object、$content);
} catch (OssException $e) {
print $e->getMessage();
}
Python
# -*-コーディング: utf-8 -*-
oss2のインポート
oss2.credentialsからEnvironmentVariableCredentialsProviderをインポート
# バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。
endpoint = 'https:// oss-cn-hangzhou.aliyuncs.com'
# 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET、およびOSS_SESSION_TOKEN環境変数が設定されていることを確認してください。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# バケットの名前を指定します。
bucket_name = 'examplebucket'
# オブジェクトのフルパスとアップロードする文字列を指定します。 バケット名をフルパスに含めないでください。
object_name = 'exampleobject.txt'
# StsAuthインスタンスに基づいてバケットを初期化します。
bucket = oss2.Bucket(auth、endpoint、bucket_name)
# オブジェクトをアップロードします。
result = bucket.put_object(object_name, "hello world")
プリント (result.status)
行く
パッケージメイン
import (import (import)
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"os"
)
func main() {
// 環境変数から一時的なアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET、およびOSS_SESSION_TOKEN環境変数が設定されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// Create an OSSClient instance.
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 実際のエンドポイントを指定します。
client, err := oss.New("yourEndpoint", ", " ", ", oss.SetCredentialsProvider(&provider))
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// バケットの名前を指定します。 例: examplebucket.
bucketName := "examplebucket"
// オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: exampledir/exampleobject.txt。
objectName := "exampledir/exampleobject.txt"
// ローカルファイルのフルパスを指定します。 例: D :\\ localpath\\examplefile.txt。
filepath := "D :\\ localpath\\examplefile.txt"
bucket,err := client.Bucket(bucketName)
// STSから取得した一時的なアクセス資格情報を使用して、サードパーティのユーザーにオブジェクトをアップロードする権限を付与します。
err = bucket.PutObjectFromFile(objectName,filepath)
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println (「アップロード成功」)
}
署名付きURLを使用してサードパーティユーザーにOSSへのオブジェクトのアップロードを許可する
単純なオブジェクトアップロードのシナリオでは、アプリケーションサーバーでOSS SDKを使用して、PutObject操作を呼び出すために必要な署名付きURLを取得できます。 その後、クライアントは署名付きURLを使用して、OSS SDKを使用せずにオブジェクトをアップロードできます。 このソリューションは、マルチパートアップロードと再開可能アップロードには適していません。 アプリケーションサーバは、各部分の署名付きURLを生成し、署名付きURLをクライアントに返す。 これは、アプリケーションサーバとの対話の数およびネットワーク要求の複雑さを増大させる。 さらに、クライアントは、部品の内容または順序を修正することができる。 これにより、無効な結合オブジェクトが生成されます。 詳細については、「URLへの署名の追加」をご参照ください。
重要 STSの一時アクセス資格情報と署名付きURLに有効期間を指定する必要があります。 一時的なアクセス資格情報を使用して、オブジェクトのアップロードやダウンロードなどの操作を実行するために使用される署名付きURLを生成する場合、最小有効期間が優先されます。 たとえば、一時的なアクセス資格情報の有効期間を1,200秒に設定し、資格情報を使用して生成された署名付きURLの有効期間を3,600秒に設定できます。 この場合、STSの一時アクセス資格情報の有効期限が切れた後は、署名付きURLを使用してオブジェクトをアップロードすることはできません。
OSS SDKの使用
次のサンプルコードは、署名付きURLを使用して、一般的なプログラミング言語のOSS SDKを使用して、サードパーティユーザーにオブジェクトをOSSにアップロードすることを許可する方法の例を示しています。 他のプログラミング言語でOSS SDKを使用してこの操作を実行する方法の詳細については、「概要」をご参照ください。
Java
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.int ernal.OSSHeadersをインポートします。com.aliyun.oss.mo del.GeneratePresignedUrlRequestをインポートします。com.aliyun.oss.mo del.StorageClassをインポートします。org.apache.http.HttpEntityをインポートします。org.apache.http.client.methods.CloseableHttpResponseをインポートします。org.apache.http.client.methods.HttpPutをインポートします。org.apache.http.entity.FileEntityをインポートします。org.apache.http.impl.client.CloseableHttpClientをインポートします。org.apache.http.impl.client.HttpClientsをインポートします。java.io.* をインポートします。impor t java.net.URL;
java.util.* をインポートします。java.util.Dateをインポートします。public classデモ {
public static void main(String[] args) Throwable {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス資格情報を取得します。 コードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数を指定していることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// バケットの名前を指定します。 例: examplebucket.
String bucketName = "examplebucket";
// オブジェクトのフルパスを指定します。 例: exampleobject.txt。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
// アップロードするローカルファイルのフルパスを指定します。 デフォルトでは、ローカルファイルのフルパスを指定しない場合、サンプルプログラムが属するプロジェクトのパスからローカルファイルがアップロードされます。
文字列pathName = "D :\\ localpath\\examplefile.txt";
// Create an OSSClient instance.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
// リクエストヘッダーを指定します。
Map<String, String> headers = new HashMap<String, String>();
/* // オブジェクトのストレージクラスを指定します。
headers.put(OSSHeaders.STORAGE_CLASS, StorageClass.Standard.toString());
// ContentTypeを指定します。
headers.put(OSSHeaders.CONTENT_TYPE、"text/txt");* /
// ユーザーメタデータを指定します。
Map<String, String> userMetadata = new HashMap<String, String>();
/* userMetadata.put("key1","value1");
userMetadata.put("key2","value2");* /
URL signedUrl = null;
try {
// 署名付きURLの有効期間を指定します。 単位:ミリ秒。 この例では、有効期間は1時間に設定されています。
日付の有効期限=新しい日付 (new Date().getTime() + 3600 * 1000L);
// Generate the signed URL.
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
// リクエストの有効期限を指定します。
request.setExpiration(expiration);
// リクエストにヘッダーを追加します。
request.setHeaders (ヘッダー);
// ユーザーメタデータを指定します。
request.setUserMetadata(userMetadata);
// HTTP PUTリクエストを許可する署名付きURLを生成します。
signedUrl = ossClient.generatePresignedUrl (要求);
// 署名されたURLを表示します。
System.out.println("signed url for putObject: " + signedUrl);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "しかし、何らかの理由でエラー応答で拒否されました。");
System.out.println("エラーメッセージ:" + oe.getErrorMessage());
System.out.println("エラーコード:" + oe.getErrorCode());
System.out.println("リクエストID:" + oe.getRequestId());
System.out.println("ホストID:" + oe.getHostId());
} catch (ClientException e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
}
// 署名付きURLを使用して、サードパーティユーザーにオブジェクトのアップロードを許可します。 この例では、HttpClientsが使用されます。
putObjectWithHttp(signedUrl, pathName, headers, userMetadata);
}
public static void putObjectWithHttp(URL signedUrl、String pathName、Map<String、String> ヘッダー、Map<String、String> userMetadata) はIOException {をスローします
CloseableHttpClient httpClient = null;
CloseableHttpResponse応答=null;
try {
HttpPut put = new HttpPut(signedUrl.toString());
HttpEntityエンティティ=new FileEntity(new File(pathName));
put.setEntity (エンティティ);
// 署名付きURLの生成時にユーザーメタデータやストレージクラスなどのヘッダーを設定する場合、署名付きURLを使用してオブジェクトをアップロードするときに、これらのヘッダーをサーバーに送信する必要があります。 署名のヘッダーがサーバーに送信されたヘッダーと一致しない場合、署名エラーが報告されます。
for(Map.Entryヘッダー: headers.entrySet()){
put.addHeader(header.getKey().toString(),header.getValue().toString());
}
for(Map.Entry meta: userMetadata.entrySet()){
// userMetaが使用されている場合、x-oss-metaプレフィックスがuserMetaに追加されます。 他のメソッドを使用してオブジェクトアップロード用の署名付きURLを生成する場合、x-oss-meta- prefixもuserMetaに追加されます。
put.addHeader("x-oss-meta-" + meta.getKey().toString(), meta.getValue().toString());
}
httpClient = HttpClients.createDefault();
応答=httpClient.exeかわいい (置く);
System.out.println("Upload status code:" + response.getStatusLine().getStatusCode());
if(response.getStatusLine().getStatusCode() == 200){
System.out.println("ネットワークライブラリを使用してオブジェクトを正常にアップロードする");
}
System.out.println(response.toString());
} catch (例外e){
e.printStackTrace();
} 最後に{
response.close();
httpClient.close();
}
}
}
PHP
<?php
if (is_file(__DIR__) 。 '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__) 。 '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
OSS\OssClientを使用します。OSS\Core\OssExceptionを使用します。OSS\Http\RequestCoreを使用します。OSS\Http\ResponseCoreを使用します。// サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。
$end point = "yourEndpoint";
// バケットの名前を指定します。
$bucket= "examplebucket";
// オブジェクトのフルパスを指定します。 オブジェクトのフルパスにバケット名を含めないでください。
$object = "exampleobject.txt";
// 署名付きURLの有効期間を3,600秒に設定します。
$timeout = 3600;
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
// Generate the signed URL.
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT");
} catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage()) 。 "\n");
戻ります。}
print(__FUNCTION__) 。 ": signedUrl: " 。 $signedUrl。 "\n");
Python
# -*-コーディング: utf-8 -*-
oss2のインポート
oss2.credentialsからEnvironmentVariableCredentialsProviderをインポート
インポートリクエスト
# 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。
# バケット名を指定します。 例: examplebucket.
bucket = oss2.Bucket(auth, 'https:// oss-cn-hangzhou.aliyuncs.com ', 'examplebucket')
# オブジェクトのフルパスを指定します。 例: exampledir/exampleobject.txt。 バケット名をフルパスに含めないでください。
object_name = 'exampledir/exampleobject.txt'
# ヘッダーを指定します。
headers = dict()
# Content-Typeパラメーターを指定します。
# headers['Content-Type'] = 'text/txt'
# ストレージクラスを指定します。
# headers["x-oss-storage-class"] = "Standard"
# オブジェクトのアップロードに使用される署名付きURLを生成します。 URLの有効期間を60秒に設定します。
# デフォルトでは、署名付きURLが生成されると、OSSはオブジェクトのフルパスのスラッシュ (/) をエスケープ文字として識別します。 したがって、署名付きURLを直接使用することはできません。
# slash_safeパラメーターをTrueに設定します。 このように、OSSはオブジェクトのフルパスのスラッシュ (/) をエスケープ文字として識別しません。 次に、生成された署名付きURLを使用してオブジェクトをアップロードできます。
url = bucket.sign_url('PUT', object_name, 60, slash_safe=True, headers=headers)
print('Signed URL:', url)
# 署名付きURLを使用してオブジェクトをアップロードします。 要求は例として使用されます。
# ローカルファイルのフルパスを指定します。 例: D :\\ exampledir\\examplefile.txt。
requests.put(url, data=open('D :\\ exampledir\\examplefile.txt ', 'rb').read(), headers=headers)
行く
パッケージメイン
import (import (import)
"fmt"
"os"
「github.com/aliyun/aliyun-oss-go-sdk/oss」
)
func HandleError (エラーエラー) {
fmt.Println("Error:", err)
os.Exit(-1)
}
func main() {
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// OSSClientインスタンスを作成します。
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 実際のエンドポイントを指定します。
client, err := oss.New("yourEndpoint", ", " ", ", oss.SetCredentialsProvider(&provider))
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// バケットの名前を指定します。 例: examplebucket.
bucketName := "examplebucket"
// オブジェクトのフルパスを指定します。 例: exampledir/exampleobject.txt。 バケット名をフルパスに含めないでください。
objectName := "exampledir/exampleobject.txt"
bucket, err := client.Bucket(bucketName)
if err! =nil {
HandleError(err)
}
// オブジェクトをアップロードするための有効期間を指定した署名付きURLを生成します。 この例では、URLの有効期間は60秒です。
signedURL, err := bucket.SignURL(objectName, oss.HTTPPut, 60)
if err! =nil {
HandleError(err)
}
// カスタムパラメーターを含む署名付きURLを使用してブラウザーからオブジェクトにアクセスするには、URLに含まれるContentTypeパラメーターの値が、リクエストで指定されたContentTypeの値と同じであることを確認します。
options := []oss.Option{
oss.Meta("myprop", "mypropval"),
oss.ContentType("text/plain") 、
}
signedURL, err = bucket.SignURL(objectName, oss.HTTPPut, 60, options...)
if err! =nil {
HandleError(err)
}
fmt.Printf("Sign Url:% s\n", signedURL)
}