iOS SDK提供了STS鑒權模式、自簽名模式以及URL簽名的方式來保障移動終端的安全性。
注意事項
無論是STS鑒權模式還是自簽名模式,您實現的回呼函數都需要保證調用時Token、Signature的返回結果。如果您需要實現向業務Server擷取Token、Signature的網路請求,建議調用網路程式庫的同步介面。回調都是在SDK發起具體請求時,在請求的子線程中執行,所以不會阻塞主線程。
STS鑒權模式
通過STS臨時授權訪問OSS的步驟如下:
擷取臨時訪問憑證
臨時訪問憑證包括臨時存取金鑰(AccessKey ID和AccessKey Secret)和安全性權杖(SecurityToken)。臨時訪問憑證有效時間單位為秒,最小值為900,最大值以當前角色設定的最大會話時間為準。更多資訊,請參見設定RAM角色最大會話時間。
您可以通過以下兩種方式擷取臨時訪問憑證。
方式一
通過調用STS服務的AssumeRole介面擷取臨時訪問憑證。
方式二
通過各語言STS SDK擷取臨時訪問憑證。
使用臨時訪問憑證初始化SDK
id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"<StsToken.AccessKeyId>" secretKeyId:@"<StsToken.SecretKeyId>" securityToken:@"<StsToken.SecurityToken>"]; client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
說明如果您需要使用OSSAuthCredentialProvider初始化SDK,請參見初始化。
通過臨時訪問憑證初始化SDK時,需要注意StsToken的有效時間。以下代碼用於判斷StsToken的有效時間:
NSDateFormatter * fm = [NSDateFormatter new]; fm.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; [fm setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; NSDate *expirationDate = [fm dateFromString:@"<StsToken.Expiration>"]; NSTimeInterval interval = [expirationDate timeIntervalSinceDate:[NSDate date]]; // 即將到期,有效時間小於5分鐘。 if (interval < 5 * 60) { id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"<StsToken.AccessKeyId>" secretKeyId:@"<StsToken.SecretKeyId>" securityToken:@"<StsToken.SecurityToken>"]; client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential]; }
手動更新StsToken
當判斷StsToken即將到期時,您可以重新構造OSSClient,也可以通過如下方式更新CredentialProvider。
id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"<StsToken.AccessKeyId>" secretKeyId:@"<StsToken.SecretKeyId>" securityToken:@"<StsToken.SecurityToken>"]; client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
自動更新StsToken
如果您期望SDK自動更新StsToken,那麼您需要在SDK的應用中實現回調。通過您實現回調的方式去擷取Federation Token(即StsToken),SDK會使用此StsToken來進行加簽處理,並在需要更新時主動調用此回調來擷取StsToken。
id<OSSCredentialProvider> credential = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * { // 您需要在此處實現擷取一個FederationToken,並構造成OSSFederationToken對象返回。 // 如果由於某種原因擷取失敗,直接返回nil。 OSSFederationToken * token; // 從您的伺服器中擷取token。 ... return token; }]; client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
說明如果您已經通過其他方式擷取了StsToken所需的各個欄位,也可以在回調中直接返回StsToken。但您需要手動處理StsToken的更新,且更新後重新設定該OSSClient執行個體的OSSCredentialProvider。
假設您訪問的Server地址為http://localhost:8080/distribute-token.json,則返回的資料如下:
{ "StatusCode": 200, "AccessKeyId":"STS.iA645eTOXEqP3cg3****", "AccessKeySecret":"rV3VQrpFQ4BsyHSAvi5NVLpPIVffDJv4LojU****", "Expiration":"2015-11-03T09:52:59Z", "SecurityToken":"CAES7QIIARKAAZPlqaN9ILiQZPS+JDkS/GSZN45RLx4YS/p3OgaUC+oJl3XSlbJ7StKpQ****" }
實現OSSFederationCredentialProvider的樣本如下。
id<OSSCredentialProvider> credential2 = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * { // 構造請求訪問您的業務Server。 NSURL * url = [NSURL URLWithString:@"http://localhost:8080/distribute-token.json"]; // 通過request設定自有伺服器需要的參數。 NSURLRequest * request = [NSURLRequest requestWithURL:url]; OSSTaskCompletionSource * tcs = [OSSTaskCompletionSource taskCompletionSource]; NSURLSession * session = [NSURLSession sharedSession]; // 發送請求。 NSURLSessionTask * sessionTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { [tcs setError:error]; return; } [tcs setResult:data]; }]; [sessionTask resume]; // 需要阻塞等待請求返回。 [tcs.task waitUntilFinished]; // 解析結果。 if (tcs.task.error) { NSLog(@"get token error: %@", tcs.task.error); return nil; } else { // 返回資料為JSON格式,需要解析返回資料得到token的各個欄位。 NSDictionary * object = [NSJSONSerialization JSONObjectWithData:tcs.task.result options:kNilOptions error:nil]; OSSFederationToken * token = [OSSFederationToken new]; token.tAccessKey = [object objectForKey:@"AccessKeyId"]; token.tSecretKey = [object objectForKey:@"AccessKeySecret"]; token.tToken = [object objectForKey:@"SecurityToken"]; token.expirationTimeInGMTFormat = [object objectForKey:@"Expiration"]; NSLog(@"get token: %@", token); return token; } }];
簽名URL
注意事項
產生簽名URL過程中,SDK利用本機存放區的密鑰資訊,根據特定演算法計算出簽名(signature),然後將其附加到URL上,以確保URL的有效性和安全性。這一系列計算和構造URL的操作都是在用戶端完成,不涉及網路請求到服務端。因此,產生簽名URL時不需要授予調用者特定許可權。但是,為避免第三方使用者無法對簽名URL授權的資源執行相關操作,需要確保調用產生簽名URL介面的身份主體被授予對應的許可權。
例如,通過簽名URL上傳檔案時,需要授予oss:PutObject許可權。通過簽名URL下載或預覽檔案時,需要授予oss:GetObject許可權。
通過以下樣本產生的簽名URL中如果包含特殊符號
+
,可能出現無法正常訪問該簽名URL的現象。如需正常訪問該簽名URL,請將簽名URL中的+
替換為%2B
。