デフォルトでは、Object Storage Service (OSS) バケット内のオブジェクトのアクセス制御リスト (ACL) は非公開です。オブジェクト所有者のみがオブジェクトにアクセスする権限を持っています。OSS SDK for Java を使用して、HTTP GET リクエストを許可し、有効期間を持つ署名付き URL を生成し、その署名付き URL をユーザーと共有することで、ユーザーが一時的にオブジェクトをダウンロードできるようにすることができます。有効期間内であれば、ユーザーはオブジェクトを繰り返しダウンロードできます。有効期間が終了すると、ユーザーは新しい署名付き URL を取得する必要があります。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用しています。OSS と同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、環境変数からアクセス認証情報を取得しています。アクセス認証情報を設定する方法の詳細については、「アクセス認証情報を設定する」をご参照ください。
このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスを作成しています。カスタムドメイン名または Security Token Service (STS) を使用して OSSClient インスタンスを作成する場合は、「一般的なシナリオの設定例」をご参照ください。
HTTP GET リクエストを許可する署名付き URL を生成するには、
oss:GetObject
権限が必要です。詳細については、「RAM ユーザーにカスタムポリシーをアタッチする」をご参照ください。説明OSS SDK for Java を使用して署名付き URL を生成する場合、SDK はローカルコンピュータに保存されているキー情報に基づいて特定のアルゴリズムを使用して署名を計算し、その署名を URL に追加して URL の有効性とセキュリティを確保します。署名の計算と URL の構築はクライアント側で行われます。ネットワーク経由でサーバーにリクエストを送信する必要はありません。そのため、呼び出し元は、OSS SDK for Java を使用して署名付き URL を生成するための特定の権限を付与される必要はありません。ただし、サードパーティユーザーが署名付き URL によって承認されたリソースに対して関連操作を実行できるようにするには、署名付き URL を生成する API 操作を呼び出す呼び出し元に、対応する権限があることを確認する必要があります。
このトピックでは、有効期間が 7 日間の V4 署名付き URL を使用しています。詳細については、「(推奨) URL に V4 署名を含める」をご参照ください。
プロセス
次の図は、署名付き URL を使用してオブジェクトをダウンロードする方法を示しています。
サンプルコード
次のサンプルコードは、HTTP GET リクエストを許可する署名付き URL を生成する方法の例を示しています。
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; import java.net.URL; import java.util.Date; public class Demo { public static void main(String[] args) throws 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。オブジェクトの完全なパスにバケット名を含めないでください。 String objectName = "exampleobject.txt"; // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。 String region = "cn-hangzhou"; // OSSClient インスタンスを作成します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // 署名付き URL の有効期間を指定します。単位: ミリ秒。この例では、有効期間は 1 時間に設定されています。 Date expiration = new Date(new Date().getTime() + 3600 * 1000L); // HTTP GET リクエストを許可する署名付き URL を生成します。この例では、追加の リクエストヘッダー は指定されていません。他のユーザーは、ブラウザ を使用して関連コンテンツに直接アクセスできます。 URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration); System.out.println(url); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }
次のサンプルコードは、HTTP GET リクエストを許可する署名付き 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"; // ダウンロードしたオブジェクトを保存するパスを、オブジェクト名と拡張子を含めて指定します。 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"; 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********" 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********" 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"; 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); // このステップは、リンクがドキュメントに存在することを保証します。 link.click(); // リンクをクリックしてダウンロードをシミュレートします。 link.remove(); // オブジェクトがダウンロードされたら、リンクを削除します。 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"; 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; }
その他のシナリオ
特定のバージョンのオブジェクトに対する HTTP GET リクエストを許可する署名付き URL を生成する
特定の リクエスト ヘッダー を含む署名付き URL を使用してオブジェクトをダウンロードする
カスタムドメイン名を使用して署名付き URL を生成する
関連情報
署名付き URL を使用してオブジェクトをダウンロードするために使用される完全なサンプルコードについては、GitHub をご覧ください。
署名付き URL を使用してオブジェクトをダウンロードするために呼び出すことができる API 操作の詳細については、「GeneratePresignedUrlRequest」をご参照ください。