すべてのプロダクト
Search
ドキュメントセンター

:アクセス権限

最終更新日:Mar 05, 2024

Object Storage Service (OSS) SDK for Androidは、Security Token Service (STS) 認証モード、自己署名モード、および署名付きURLを提供し、モバイルデバイスのデータセキュリティを確保します。

背景情報

STS認証モードまたは自己署名モードを使用する場合は、実装するコールバック関数がセキュリティトークンと署名を返すことができることを確認してください。 コールバック関数でリクエストを送信してアプリサーバーからトークンと署名を取得する必要がある場合は、ネットワークライブラリに含まれる同期API操作を呼び出すことを推奨します。 コールバック関数は、SDKによって生成されたリクエストの子スレッドで実行され、メインスレッドをブロックしません。

STS認証モード

説明

STS認証モードを使用するには、まずAlibaba Cloud Resource Access Management (RAM) を有効化する必要があります。

STSを使用して、OSSへの一時アクセスを許可できます。 STSは、一時的なアクセストークンを提供するwebサービスです。 STSを使用して、管理されているサードパーティのアプリケーションまたはRAMユーザーに、カスタムの有効期間とカスタムのアクセス許可を持つ一時的なアクセス資格情報を付与できます。 STSの詳細については、「STSの概要」をご参照ください。

STSには次の利点があります。

  • 一時的なアクセストークンを生成し、そのアクセストークンをサードパーティのアプリケーションに送信するだけで済みます。 サードパーティのアプリケーションにAccessKeyペアを提供する必要はありません。 トークンのアクセス権限と有効期間を指定できます。

  • トークンは、有効期間後に自動的に期限切れになります。 したがって、トークンのアクセス権限を手動で取り消す必要はありません。

STSが提供する一時的なアクセス資格情報を使用してOSSにアクセスするには、次の操作を実行します。

  1. 一時的なアクセス資格情報を取得します。

    一時的なアクセス資格情報には、セキュリティトークンと、AccessKey IDとAccessKeyシークレットで構成される一時的なAccessKeyペアが含まれます。 一時的なアクセス資格情報の最小有効期間は900秒です。 一時的なアクセス資格情報の最大有効期間は、現在のロールに指定されている最大セッション期間です。 詳細については、「RAMロールの最大セッション期間の指定」をご参照ください。

    次のいずれかの方法を使用して、一時的なアクセス資格情報を取得できます。

    • 方法1:

      AssumeRole操作を呼び出して、一時的なアクセス資格情報を取得します。

    • 方法2:

      STS SDKを使用して一時的なアクセス資格情報を取得します。 詳細については、「概要」をご参照ください。

  2. 一時的なアクセス資格情報を使用して、OSS SDK for Androidを初期化します。

    String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    
    OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider("StsToken.AccessKeyId" 、"StsToken.SecretKeyId" 、"StsToken.SecurityToken");
    
    OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider); 

    一時的なアクセス資格情報を使用してSDKを初期化する場合は、STSトークンの有効期間に注意してください。

    次のサンプルコードは、トークンの残りの有効期間が5分未満の場合にSTSトークンを更新します。

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    日付日付=sdf.parse("<StsToken.Expiration>");
    long expiration = date.getTime() / 1000;
    // 残りの有効期間が5分未満の場合、STSトークンを更新します。 
    if (DateUtil.getFixedSkewedTimeMillis() / 1000> 有効期限-5*60) {
        oss.updateCredentialProvider (新しいOSSStsTokenCredentialProvider("StsToken.AccessKeyId" 、"StsToken.SecretKeyId" 、"StsToken.SecurityToken"));
    } 
    • STSトークンを手動で更新する

      STSトークンの有効期限が近づいたら、次のコマンドを実行して、別のOSSClientインスタンスを作成するか、CredentialProviderを更新できます。

      oss.updateCredentialProvider (新しいOSSStsTokenCredentialProvider("StsToken.AccessKeyId" 、"StsToken.SecretKeyId" 、"StsToken.SecurityToken"));
    • STSトークンを自動的に更新する

      SDKがSTSトークンを自動的に更新する場合は、アプリにコールバックを実装する必要があります。 アプリはコールバックを使用してフェデレーショントークン (STSトークン) を取得し、そのトークンをSDKに返します。 SDKはSTSトークンを使用して署名を生成します。 STSトークンを更新する必要がある場合、SDKはコールバックを呼び出して新しいトークンを取得します。

      String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
      
      OSSCredentialProvider credentialProvider = new OSSFederationCredentialProvider() {
      
          @オーバーライド
          public OSSFederationToken getFederationToken() {
          // フェデレーショントークンを取得し、トークンを構築してから、トークンをOSSFederationTokenオブジェクトとして返します。 フェデレーショントークンが取得されていない場合、nullが返されます。 
      
              OSSFederationTokenトークン;
              // サーバーからフェデレーショントークンを取得します。 
              return token;
          }
      };
      
      OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider); 
      説明

      他の方法でSTSトークンを生成するために必要なすべてのフィールドを取得した場合は、コールバックでトークンを直接返すことができます。 この場合、トークンを手動で更新してから、OSSClientインスタンスのOSSCredentialProviderを再設定する必要があります。

      トークンを要求するサーバーのURLがhttp:// localhost:8080/distribute-token.jsonの場合、次のデータが返されます。

      {
          "StatusCode": 200、
          "AccessKeyId":"STS.iA645eTOXEqP3cg3 ****" 、
          "AccessKeySecret":"rV3VQrpFQ4BsyHSAvi5NVLpPIVffDJv4LojU ****" 、
          "有効期限":"2015-11-03T09:52:59Z" 、
          "SecurityToken":"CAES7QIIARKAAZPlqaN9ILiQZPS JDkS/GSZN45RLx4YS/p3OgaUC + oJl3XSlbJ7StKpQ ****"} 

      次のサンプルコードは、OSSFederationCredentialProviderの実装方法の例を示しています。

      OSSCredentialProvider credetialProvider = new OSSFederationCredentialProvider() {
          @オーバーライド
          public OSSFederationToken getFederationToken() {
              try {
                  URL stsUrl=新しいURL("http:// localhost:8080/distribute-token.json");
                  HttpURLConnection conn = (HttpURLConnection) stsUrl.openConnection();
                  InputStream input = conn.getInputStream();
                  文字列jsonText = IOUtils.readStreamAsString(input, OSSConstants.DEFAULT_CHARSET_NAME);
                  JSONObject jsonObjs=新しいJSONObject(jsonText);
                  String ak = jsonObjs.getString("AccessKeyId");
                  String sk = jsonObjs.getString("AccessKeySecret");
                  String token = jsonObjs.getString("SecurityToken");
                  String expiration = jsonObjs.getString("Expiration");
                  return new OSSFederationToken(ak, sk, token, expiration);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              ヌルを返します。
          }
      };                    

自己署名モード

image

次の操作を実行して、AccessKey IDとAccessKeyシークレットを自分のサーバーに保存し、サーバー上のクライアント情報に署名できます。

  1. クライアントから署名する文字列を取得し、自分のサーバーに送信します。

    1. OSS SDK for Androidが提供するOSSCustomSignerCredentialProviderのsignContentメソッドを使用して、リクエストの作成時に文字列の署名を取得します。

    2. 文字列署名を自分のサーバーに送信します。

  2. 独自のサーバーで文字列に署名し、署名された文字列をクライアントに返します。

    1. 指定された署名アルゴリズムを使用して文字列に署名します。 詳細については、「承認ヘッダーにV1署名を含める」をご参照ください。

      署名アルゴリズムV1は、signature = "OSS" + AccessKeyId + ":" + base64(hmac-sha1(AccessKeySecret, content)) の形式に従います。

    2. 署名された文字列をクライアントに返します。

      たとえば、サーバーのURLはhttp:// localhost:8080/signです。 コンテンツをサーバーに送信して署名を生成できます。 次に、サーバは、署名をクライアントに返す。 次のサンプルコードは、署名を取得する方法の例を示しています。

      String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
      
      OSSCredentialProvider credentialProvider = new OSSCustomSignerCredentialProvider() {
          @オーバーライド
          public String signContent (文字列コンテンツ) {
              URL stsUrl=新しいURL("http:// localhost:8080/sign?content=" + content);
              HttpURLConnection conn = (HttpURLConnection) stsUrl.openConnection();
              InputStream input = conn.getInputStream();
              文字列jsonText = IOUtils.readStreamAsString(input, OSSConstants.DEFAULT_CHARSET_NAME);
              JSONObject jsonObjs=新しいJSONObject(jsonText);
              String signature = jsonObjs.getString("signature");
              署名を返します。
          }
      };
      OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider); 
  3. クライアントの署名された文字列を認証のためにOSSサーバーに送信します。

署名付き URL

署名付きURLを生成し、一時的なアクセスのためのURLを訪問者に提供できます。 署名付きURLを生成するときに、URLの有効期間を指定して、訪問者が指定されたデータにアクセスできる期間を制限できます。

重要

次のサンプルコードを使用して生成された署名付きURLには、プラス記号 (+) が含まれる場合があります。 この場合、URLのプラス記号 (+) を % 2Bに置き換える必要があります。 そうでない場合、署名付きURLにアクセスできない可能性があります。

次のサンプルコードでは、署名付きURLを生成し、署名付きURLを使用してオブジェクトをアップロードおよびダウンロードする方法の例を示します。

署名付きURLを生成し、そのURLを使用してオブジェクトをアップロードする

  1. 署名付きURLを生成します。

    // バケットの名前を指定します。 例: examplebucket. 
    String bucketName = "examplebucket";
    // ソースオブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: exampleobject.txt。 
    String objectKey = "exampleobject.txt";
    // Content-Typeを指定します。 
    String contentType = "application/octet-stream";
    文字列url = null;
    try {
        // オブジェクトのアップロードに使用する署名付きURLを生成します。 
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
        // 署名付きURLの有効期間を30分に設定します。 
        request.setExpiration(30*60);
        request.setContentType(contentType);    
        request.setMethod(HttpMethod.PUT);
        url = mOss.presignConstrainedObjectURL (リクエスト);
        Log.d("url" 、url);
    } catch (ClientException e) {
        e.printStackTrace();
    } 
  2. 署名付きURLを使用してオブジェクトをアップロードします。

    // 生成された署名付きURLを入力します。 
    文字列url = "";
    // ローカルファイルのフルパスを指定します。 
    String localFile = "/storage/emulated/0/oss/examplefile";
    // Content-Typeを指定します。 
    String contentType = "application/octet-stream";
    // 署名付きURLを使用してオブジェクトをアップロードします。 
    OkHttpClient client = new OkHttpClient();
    Request putRequest = new Request.Builder()
            . url(url)
            . put(RequestBody.create(MediaType.parse(contentType), new File(localFile)))
            . build();
    client.newCall(putRequest).enqueue(new Callback() {
        @オーバーライド
        public void onFailure (コールコール, IOException e) {
            e.printStackTrace();
        }
    
        @オーバーライド
        public void onResponse (コールコール、レスポンスレスポンス) throws IOException {
            Log.d("response", response.body().string());
        }
    });

署名付きURLを生成し、署名付きURLを使用してオブジェクトをダウンロードする

  1. 署名付きURLを生成します。

    // バケットの名前を指定します。 例: examplebucket. 
    String bucketName = "examplebucket";
    // ソースオブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: exampleobject.txt。 
    String objectKey = "exampleobject.txt";
    文字列url = null;
    try {
        // オブジェクトのダウンロードに使用する署名付きURLを生成します。 
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
        // 署名付きURLの有効期間を30分に設定します。 
        request.setExpiration(30*60);
        request.setMethod(HttpMethod.GET);
        url = mOss.presignConstrainedObjectURL (リクエスト);
        Log.d("url" 、url);
    } catch (ClientException e) {
        e.printStackTrace();
    } 
  2. 署名付きURLを使用してオブジェクトをダウンロードします。

    // 生成された署名付きURLを入力します。 
    文字列url = "";
    OkHttpClient client = new OkHttpClient();
    // 署名付きURLを使用してオブジェクトをダウンロードします。 
    Request getRequest = new Request.Builder()
            . url(url)
            . get()
            . build();
    client.newCall(getRequest).enqueue(new Callback() {
        @オーバーライド
        public void onFailure (コールコール, IOException e) {
            e.printStackTrace();
        }
    
        @オーバーライド
        public void onResponse (コールコール、レスポンスレスポンス) throws IOException {
            if (response.code() == 203 | | response.code() >= 300) {
                Log.d("ダウンロード" 、"失敗");
                Log.d("download", response.body().string());
                return;
            }
            // オブジェクトがダウンロードされます。 
            InputStream inputStream = response.body().byteStream();
    
            byte[] buffer = new byte[2048];
            int len;
    
            while ((len = inputStream.read(buffer)) ! = -1) {
                // ダウンロードしたデータを処理します。 たとえば、画像を表示したり、オブジェクトに書き込み操作を実行したりします。 
            }
        }
    });