edit-icon download-icon

アクセス制御

最終更新日: Dec 19, 2017

モバイルデバイスは信頼できない環境です。したがって、SDKには、STS認証モードと自己署名モードの2つの認証モードが用意されています。

STS認証モード

前書き

OSSは、Alibaba Cloud STSサービスを使用してアクセスの許可を一時的に付与することができます。Alibaba Cloud STS(Security Token Service)は、クラウドコンピューティングのユーザーに一時的なアクセストークンを提供するWebサービスです。STSを使用すると、サードパーティのアプリケーションまたは連合ユーザー(ユーザーIDを管理できます)に、カスタム有効期間とアクセス権を持つアクセス資格情報を割り当てることができます。アプリケーションのアクセス信用証明は、FederationTokenと呼ばれます。サードパーティのアプリケーションまたはフェデレーションユーザーは、これらのアクセス資格情報を使用してAlibaba Cloud APIを直接呼び出したり、Alibaba Cloudが提供するSDKを使用してクラウド製品のAPIにアクセスすることができます。

STSのメリット

  • 長期キー(AccessKey)をサードパーティアプリケーションに開示する必要はありません。アクセストークンを生成し、それを第三者アプリケーションに送信すればよいだけです。このトークンのアクセス許可と妥当性をカスタマイズできます。

  • 権限を取り消す必要はありません。有効期限が切れると、アクセストークンは自動的に無効になります。

たとえば、アプリケーションでの対話プロセスを次の図に示します。

STSの使い方

  1. アプリケーションにログオンします。

    アプリケーションIDを管理できます。ID管理システムをカスタマイズしたり、外部WebアカウントまたはOpenIDを使用することができます。各有効なアプリユーザーに対して、AppServerは最小アクセス許可を正確に定義することができます。

  2. AppServerは、セキュリティトークン(SecurityToken)をSTSに要求します。

    1. STSが呼び出される前に、AppServerは、アプリケーションユーザーの最小アクセス許可(ポリシー構文内)と承認の有効期限を判断する必要があります。

    2. セキュリティトークンは、STS AssumeRole APIを呼び出して取得できます。役割と使用方法の詳細については、「RAMユーザーガイド」の「役割の管理」を参照してください。

  3. STSは、有効なアクセス資格情報をAppServerに返します。アクセス信任状には、SecurityToken、一時的なアクセスキーのペア(AccessKeyIDとAccessKeySecret)、および有効期限が含まれています。

  4. AppServerはアクセスクレデンシャルをClientAppに返します。

    ClientAppはこの資格情報をキャッシュできます。資格情報が無効になると、ClientAppはAppServerから新しい有効なアクセス資格情報を要求する必要があります。たとえば、アクセスクレデンシャルが1時間有効である場合、ClientAppは30分ごとにアクセスクレデンシャルを更新するようにAppServerに要求できます。

  5. ClientAppはローカルにキャッシュされたアクセス資格情報を使用してAlibaba CloudサービスAPIを要求します。 クラウドサービスはSTSアクセス認証情報を検出し、認証情報をSTSサービスで検証し、それに応じてユーザー要求に応答します。

注意: この認証モードを使用するには、まず認証を有効にする必要があります Alibaba Cloud RAM service

STSTokenを直接設定する

特定の方法(ビジネスサーバーからのネットワーク要求など)によって、Appやその他のモバイルデバイスにSTSTokenを1組取得し、それを使用してSDKを初期化することができます。この方法を採用する場合は、STSTokenの有効期限に従わなければなりません。STSTokenの有効期限が近づいたら、SDKの新しいSTSTokenを更新するためのイニシアティブをとる必要があります。

初期化コードは次のとおりです。

  1. id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"<StsToken.AccessKeyId>" secretKeyId:@"<StsToken.SecretKeyId>" securityToken:@"<StsToken.SecurityToken>"];
  2. client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];

トークンが期限切れになるのを確認したら、次の方法で新しいOSSClientを再構築したり、CredentialProviderを更新したりできます。

  1. client.credentialProvider = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"<StsToken.AccessKeyId>" secretKeyId:@"<StsToken.SecretKeyId>" securityToken:@"<StsToken.SecurityToken>"];

コールバックを実装してSTSTokenを取得する

SDKで自動的にトークンの更新を管理する場合は、トークンを取得するようにSDKを構成する必要があります。SDKのアプリケーションでは、FederationToken(STSToken)を取得してトークンを返すコールバックを実装する必要があります。SDKはトークンを署名に使用します。トークンを更新する必要がある場合、SDKはコールバックを呼び出してトークンを取得します(次の図を参照)。

  1. id<OSSCredentialProvider> credential = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
  2. // Here you must implement a method to get a FederationToken and construct it into the OSSFederationToken object to return it
  3. // If the token is not obtained, "nil" is returned
  4. OSSFederationToken * token;
  5. // The following are some codes that can be used to obtain the token, for example from your server
  6. ...
  7. return token;
  8. }];
  9. client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];

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

例:

設定したサーバのURLがhttp://localhost:8080/distribute-token.jsonであるとします。URLにアクセスすると、返されるデータは次のようになります。

  1. {
  2. "StatusCode": 200,
  3. "AccessKeyId":"STS.iA645eTOXEqP3cg3VeHf",
  4. "AccessKeySecret":"rV3VQrpFQ4BsyHSAvi5NVLpPIVffDJv4LojUBZCf",
  5. "Expiration":"2015-11-03T09:52:59Z",
  6. "SecurityToken":"CAES7QIIARKAAZPlqaN9ILiQZPS+JDkS/GSZN45RLx4YS/p3OgaUC+oJl3XSlbJ7StKpQ...."}

次のコードを使用して、OSSFederationCredentialProviderインスタンスを実装することができます。

  1. id<OSSCredentialProvider> credential2 = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
  2. // Construct a request to access your business server
  3. NSURL * url = [NSURL URLWithString:@"http://localhost:8080/distribute-token.json"];
  4. NSURLRequest * request = [NSURLRequest requestWithURL:url];
  5. OSSTaskCompletionSource * tcs = [OSSTaskCompletionSource taskCompletionSource];
  6. NSURLSession * session = [NSURLSession sharedSession];
  7. // Send the request
  8. NSURLSessionTask * sessionTask = [session dataTaskWithRequest:request
  9. completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  10. if (error) {
  11. [tcs setError:error];
  12. return;
  13. }
  14. [tcs setResult:data];
  15. }];
  16. [sessionTask resume];
  17. // Use a blocking call to wait until the task is returned
  18. [tcs.task waitUntilFinished];
  19. // Parse the result
  20. if (tcs.task.error) {
  21. NSLog(@"get token error: %@", tcs.task.error);
  22. return nil;
  23. } else {
  24. // The returned data is in JSON format and you must parse it to obtain all fields of the token
  25. NSDictionary * object = [NSJSONSerialization JSONObjectWithData:tcs.task.result
  26. options:kNilOptions
  27. error:nil];
  28. OSSFederationToken * token = [OSSFederationToken new];
  29. token.tAccessKey = [object objectForKey:@"AccessKeyId"];
  30. token.tSecretKey = [object objectForKey:@"AccessKeySecret"];
  31. token.tToken = [object objectForKey:@"SecurityToken"];
  32. token.expirationTimeInGMTFormat = [object objectForKey:@"Expiration"];
  33. NSLog(@"get token: %@", token);
  34. return token;
  35. }
  36. }];

自己署名モード

  1. id<OSSCredentialProvider> credential = [[OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^NSString *(NSString *contentToSign, NSError *__autoreleasing *error) {
  2. // Here you must sign a string using the OSS-specified signature algorithm, merge the AccessKeyID with the signed string, and return the string
  3. // Generally, post the string to your business server and then return the signature
  4. // If the signing fails, "nil" is returned after the error is described
  5. NSString *signature = [OSSUtil calBase64Sha1WithData:contentToSign withSecret:@"<your accessKeySecret>"]; // The local signature is completed by using the utility function in the SDK. We recommend that you use the service server to obtain the remote signature
  6. if (signature != nil) {
  7. *error = nil;
  8. } else {
  9. *error = [NSError errorWithDomain:@"<your domain>" code:-1001 userInfo:@"<your error info>"];
  10. return nil;
  11. }
  12. return [NSString stringWithFormat:@"OSS %@:%@", @"<your accessKeyId>", signature];
  13. }];
  14. client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];

注意: STS認証モードおよび自己署名モードでは、実装されたコールバック関数を呼び出すと結果が返されるようにしてください。したがって、ネットワーク要求でビジネスサーバーからトークンと署名を取得する必要がある場合は、ネットワークライブラリの同期APIを呼び出すか、非同期から同期に変換することをお勧めします。コールバックは、メインスレッドをブロックしないSDKからの要求のサブスレッドで実行されます。