デフォルトでは、バケット内の Object Storage Service (OSS) オブジェクトのアクセス制御リスト (ACL) は非公開です。オブジェクト所有者のみが、バケットにオブジェクトをアップロードする権限を持っています。 .NET 用 OSS SDK を使用して署名付き URL を生成し、それをユーザーと共有してオブジェクトをアップロードできるようにすることができます。署名付き URL を生成する際に、有効期間を指定して、ユーザーがオブジェクトをアップロードできる期間を制限できます。署名付き URL の有効期間中は、ユーザーはその URL を使用してバケットにオブジェクトを複数回アップロードできます。オブジェクトを複数回アップロードすると、データが上書きされる可能性があります。署名付き URL の有効期間が終了すると、ユーザーは署名付き URL を使用してオブジェクトをアップロードできなくなります。ユーザーのアクセスを延長するには、署名付き URL を再生成できます。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用しています。 OSS と同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。 OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、アクセス認証情報は環境変数から取得されます。アクセス認証情報を設定する方法の詳細については、「アクセス認証情報を設定する」をご参照ください。
ファイルアップロード用の署名付き URL を生成するには、
oss:PutObject
権限が必要です。詳細については、「RAM ユーザーにカスタムポリシーをアタッチする」をご参照ください。説明SDK は特定のアルゴリズムとローカルコンピュータに保存されているキー情報を使用して署名を計算し、URL に署名を追加して URL の有効性とセキュリティを確保します。署名の計算と URL の構築はクライアント側で実行され、ネットワーク経由でサーバーにリクエストを送信することはありません。したがって、署名付き URL を生成するために特定の権限を付与される必要はありません。ただし、サードパーティユーザーがリソースに対して意図した操作を実行できるようにするには、署名付き URL を生成する ID プリンシパルが、操作を実行するための対応する権限を持っていることを確認してください。
このトピックでは、署名アルゴリズム V4 を使用して、最大 7 日間の有効期間を持つ署名付き URL を生成します。詳細については、「(推奨) URL に V4 署名を含める」をご参照ください。
次のサンプルコードを使用して生成された署名付き URL には、プラス記号 (
+
) が含まれる場合があります。この場合、署名付き URL にアクセスできるように、プラス記号+
を%2B
に置き換えます。HTTPS スキームを使用する署名付き URL を生成するには、エンドポイントのプロトコルを HTTPS に設定します。
プロセス
次の図は、HTTP PUT リクエストを許可する署名付き URL を使用して OSS にオブジェクトをアップロードする方法を示しています。
サンプルコード
次のサンプルコードは、OSS へのデータアップロード用の署名付き URL を生成して使用する方法を示しています。完全なサンプルコードについては、GitHub をご覧ください。
データアップロード用の署名付き URL を生成して使用する
署名付き URL を生成します。
using Aliyun.OSS; using Aliyun.OSS.Common; // バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 var endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。 var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID"); var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET"); // バケットの名前を指定します。例: examplebucket。 var bucketName = "examplebucket"; // オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。例: exampledir/exampleobject.txt。 var objectName = "exampledir/exampleobject.txt"; var objectContent = "More than just cloud."; // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。 const string region = "cn-hangzhou"; // ClientConfiguration インスタンスを作成し、要件に基づいてデフォルトのパラメータ設定を変更します。 var conf = new ClientConfiguration(); // V4 署名アルゴリズムを指定します。 conf.SignatureVersion = SignatureVersion.V4; // OSSClient インスタンスを作成します。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf); conf.SetRegion(region); try { // 署名付き URL を生成します。 var generatePresignedUriRequest = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Put) { // 署名付き URL の有効期間を設定します。デフォルト値: 3600。単位: 秒。 Expiration = DateTime.Now.AddHours(1), }; var signedUrl = client.GeneratePresignedUri(generatePresignedUriRequest); } catch (OssException ex) { Console.WriteLine("エラーコード: {0} で失敗しました。エラー情報: {1}。 \nRequestID:{2}\tHostID:{3}", ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId); } catch (Exception ex) { Console.WriteLine("エラー情報: {0} で失敗しました。", ex.Message); }
署名付き URL を使用してオブジェクトをアップロードします。
Curl
curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
Java
import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class Demo { public static void main(String[] args) { // HTTP GET リクエストを許可する署名付き URL に置き換えます。 String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"; // ダウンロードしたオブジェクトを保存するパスを、オブジェクト名と拡張子を含めて指定します。 String savePath = "C:/downloads/myfile.txt"; try { downloadFile(fileURL, savePath); System.out.println("ダウンロードが完了しました!"); } catch (IOException e) { System.err.println("ダウンロード中にエラーが発生しました: " + e.getMessage()); } } private static void downloadFile(String fileURL, String savePath) throws IOException { URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); // 応答コードを指定します。 int responseCode = httpConn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 入力ストリームを設定します。 InputStream inputStream = new BufferedInputStream(httpConn.getInputStream()); // 出力ストリームを設定します。 FileOutputStream outputStream = new FileOutputStream(savePath); byte[] buffer = new byte[4096]; // バッファのサイズを指定します。 int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); } else { System.out.println("ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました: " + responseCode); } httpConn.disconnect(); } }
Node.js
const https = require('https'); const fs = require('fs'); const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"; const savePath = "C:/downloads/myfile.txt"; https.get(fileURL, (response) => { if (response.statusCode === 200) { const fileStream = fs.createWriteStream(savePath); response.pipe(fileStream); fileStream.on('finish', () => { fileStream.close(); console.log("ダウンロードが完了しました!"); }); } else { console.error(`ダウンロードに失敗しました。サーバーはコードで応答しました: ${response.statusCode}`); } }).on('error', (err) => { console.error("ダウンロード中にエラーが発生しました:", err.message); });
Python
import requests file_url = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************" save_path = "C:/downloads/myfile.txt" try: response = requests.get(file_url, stream=True) if response.status_code == 200: with open(save_path, 'wb') as f: for chunk in response.iter_content(4096): f.write(chunk) print("ダウンロードが完了しました!") else: print(f"ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました: {response.status_code}") except Exception as e: print("ダウンロード中にエラーが発生しました:", e)
Go
package main import ( "io" "net/http" "os" ) func main() { fileURL := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************" savePath := "C:/downloads/myfile.txt" response, err := http.Get(fileURL) if err != nil { panic(err) } defer response.Body.Close() if response.StatusCode == http.StatusOK { outFile, err := os.Create(savePath) if err != nil { panic(err) } defer outFile.Close() _, err = io.Copy(outFile, response.Body) if err != nil { panic(err) } println("ダウンロードが完了しました!") } else { println("ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました:", response.StatusCode) } }
JavaScript
const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"; const savePath = "C:/downloads/myfile.txt"; // ダウンロードしたオブジェクトの名前を指定します。 fetch(fileURL) .then(response => { if (!response.ok) { throw new Error(`サーバーは HTTP コードを返信しました: ${response.status}`); } return response.blob(); // レスポンスのタイプを blob に変更します。 }) .then(blob => { const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = savePath; // ダウンロードしたオブジェクトの名前を指定します。 document.body.appendChild(link); // この手順により、署名付き URL がドキュメントに存在することが保証されます。 link.click(); // 署名付き URL をクリックして、オブジェクトのダウンロードをシミュレートします。 link.remove(); // オブジェクトがダウンロードされたら、署名付き URL を削除します。 console.log("ダウンロードが完了しました!"); }) .catch(error => { console.error("ダウンロード中にエラーが発生しました:", error); });
Android-Java
import android.os.AsyncTask; import android.os.Environment; import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class DownloadTask extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... params) { String fileURL = params[0]; String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // ダウンロードしたオブジェクトを保存するパスを指定します。 try { URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); int responseCode = httpConn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = new BufferedInputStream(httpConn.getInputStream()); FileOutputStream outputStream = new FileOutputStream(savePath); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); return "ダウンロードが完了しました!"; } else { return "ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました: " + responseCode; } } catch (Exception e) { return "ダウンロード中にエラーが発生しました: " + e.getMessage(); } } }
Objective-C
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { // 署名付き URL とオブジェクトを保存するパスを指定します。 NSString *fileURL = @"https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"; NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // your_username をユーザー名に置き換えます。 // URL オブジェクトを作成します。 NSURL *url = [NSURL URLWithString:fileURL]; // オブジェクトダウンロードタスクを作成します。 NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // エラーを処理します。 if (error) { NSLog(@"ダウンロード中にエラーが発生しました: %@", error.localizedDescription); return; } // オブジェクトのデータを確認します。 if (!data) { NSLog(@"データを受信しませんでした。"); return; } // オブジェクトを保存します。 NSError *writeError = nil; BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError]; if (success) { NSLog(@"ダウンロードが完了しました!"); } else { NSLog(@"ファイルを保存中にエラーが発生しました: %@", writeError.localizedDescription); } }]; // オブジェクトダウンロードタスクを開始します。 [task resume]; // メインスレッドを実行し続けて、非同期リクエストを完了します。 [[NSRunLoop currentRunLoop] run]; } return 0; }
よくある質問
署名付き URL を使用してローカルファイルをアップロードする場合、アップロード中に署名付き URL の有効期限が切れると、ファイルのアップロードは失敗しますか?
いいえ、ファイルのアップロードは、アップロードプロセス中に署名付き URL の有効期限が切れても失敗しません。
署名付き URL は、トークンの有効期間と署名の有効期間の短い方の期間によって決定される有効期間内に使用できます。
HTTP POST メソッドをサポートする署名付き URL を生成できますか?
いいえ、HTTP POST メソッドをサポートする署名付き URL は生成できません。
HTTP PUT および GET メソッドをサポートする署名付き URL のみ生成できます。 HTTP POST メソッドを使用してオブジェクトをアップロードする場合は、POST リクエストを作成する必要があります。詳細については、「PostObject」をご参照ください。