移動應用使用臨時憑證直傳
更新時間 2023-12-07 21:31:05
最近更新時間: 2023-12-07 21:31:05
分享文章
本文主要講解移動應用使用臨時憑證直傳文件的最佳實踐。
實踐背景
在移動互聯網時代,從手機里的照片到各類文件,移動端APP需要上傳到服務器的文件越來越多。開發者可以使用媒體存儲來保存這些文件,媒體存儲提供的SDK接口可以支持直接在移動端進行文件上傳。
訪問媒體存儲需要使用密鑰(AK/SK),但是如果在移動端直接使用長期密鑰訪問對象存儲,遭受黑客攻擊就可能會暴露長期密鑰,導致對象存儲中的文件泄露或被篡改,存在很大的風險。
媒體存儲提供STS角色管理功能,可以為移動端頒發一個自定義時效和權限的訪問憑證,無需在移動端暴露長期密鑰。使用STS授權訪問時,請務必按照業務情況,以最細粒度的權限原則進行授權,避免放大臨時用戶的權限,保證資源訪問安全。
應用流程
使用臨時憑證直傳時,具體應用流程如下:

實踐步驟
創建用于獲取STS訪問憑證的角色
通過媒體存儲控制臺,創建STS角色,并獲取對應的arn信息,具體可參考 STS角色管理 。
對應角色授權并且獲取STS臨時密鑰
具體可參照如下java示例:
// STS endPoint
String endPoint = "<sts-endpoint>";
// 在對象存儲控制臺訪問密鑰AccessKey和SecretKey。
String accessKey = "<access-key>";
String secretKey = "<secret-key>";
// 填寫步驟一獲取的角色ARN。
String roleArn = "<role-arn>";
// 設置臨時訪問憑證的名稱.
String roleSessionName = "<session-name>";
// 設置 Policy 允許上傳對象
String policy = "{\"Version\":\"2012-10-17\"," + "\"Statement\":[" + "{\"Effect\":\"Allow\","
+ "\"Action\":[\"s3:PutObject\"],"
+ "\"Resource\":[\"arn:aws:s3:::<bucket-name>/*\"]}" + "]}";
// 創建STS Client
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endPoint, "");
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials))
.withEndpointConfiguration(endpointConfiguration)
.build();
AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest();
assumeRoleRequest.setRoleArn(roleArn);
assumeRoleRequest.setRoleSessionName(roleSessionName);
assumeRoleRequest.setPolicy(policy);
AssumeRoleResult assumeRoleRes = stsClient.assumeRole(assumeRoleRequest);
Credentials stsCredentials = assumeRoleRes.getCredentials();
System.out.println("Expiration: " + stsCredentials.getExpiration());
System.out.println("Access Key Id: " + stsCredentials.getAccessKeyId());
System.out.println("Access Key Secret: " + stsCredentials.getSecretAccessKey());
System.out.println("Security Token: " + stsCredentials.getSessionToken());
通過臨時密鑰訪問對象存儲資源
本文以Android與IOS應用為例。
- Android
public class MyCredentialsProvider implements AWSCredentialsProvider {
private AWSCredentials credentials;
public MyCredentialsProvider(String ak, String sk, String token) {
this.credentials = new BasicSessionCredentials(ak, sk, token);
}
public synchronized AWSCredentials getCredentials() {
return credentials;
}
public synchronized void refresh() {
}
// 更新ak,sk,token
public synchronized void updateCred(String ak, String sk, String token) {
this.credentials = new BasicSessionCredentials(ak, sk, token);
}
}
String accessKey = "<your-access-key>";
String secretKey = "<your-secret-access-key>";
String endPoint = "<your-endpoint>";
String sessionToken = "<your-session-token>";
MyCredentialsProvider credProvider = new MyCredentialsProvider(accessKey, secretKey, sessionToken);
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTP);
AmazonS3Client mS3Client = new AmazonS3Client(credProvider, clientConfig);
mS3Client.setEndpoint(endPoint);
- IOS
#define ACCESS_KEY @"<your-access-key>"
#define SECRET_KEY @"<your-secret-key>"
#define ENDPOINT @"<your-endpoint>"
#define SESSION_TOKEN @"<your-session-token>"
-(id)initWithToken {
if (self = [super init]) {
AWSBasicSessionCredentialsProvider *credentialsProvider = [[AWSBasicSessionCredentialsProvider alloc] initWithAccessKey:ACCESS_KEY secretKey:SECRET_KEY sessionToken:SESSION_TOKEN];
AWSEndpoint *endPoint = [[AWSEndpoint alloc] initWithURLString:ENDPOINT];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc]
initWithRegion:AWSRegionUSEast1
endpoint:endPoint
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
self.s3 = [AWSS3 defaultS3];
}
return self;
}