前言
磁盤怎么又滿了?趕緊 快 打電話給運維擴容擴容擴容!這個問題已經是我入職新公司兩個月來,第 3 次聽到了。經過一通了解,事情原來是這樣的。雖然我們使用了阿里雲的 OSS 對象存儲服務,但是為了不暴露 AccessKeyId 以及 AccessKeySecret 給客戶端,所以全部是由客戶端上傳到我們的服務器,由我們服務器中轉上傳,其實只要上傳完成刪除相應的文件應該就不會引發磁盤空間不足的問題,奈何之前的精神小伙並沒有干這一步,文件放磁盤上當備份用。由此引發思考中轉上傳是不是太麻煩了,直傳 OSS 不香嗎? 如何保證 AccessKeyId 以及 AccessKeySecret 的安全以及 Bucket 權限問題呢?這就是下面要講的阿里雲 OSS 上的 Sts 授權模式。
STS 臨時授權訪問 OSS
OSS 可以通過阿里雲 STS(Security Token Service)進行臨時授權訪問。通過 STS,您可以為第三方應用或子用戶(即用戶身份由您自己管理的用戶)頒發一個自定義時效和權限的訪問憑證。
以上是官方原話,經過我的實踐結合理論,可以得出:我們可以通過 STS 頒發一個臨時的 AccessKeyId
,AccessKeySecret
,SecurityToken
, 用戶可以通過這3個訪問憑證對 Oss 進行相應操作。在我們申請頒布訪問憑證的時候,還可以設置對應的權限。
Coding
在使用下面測試前,請先完成 STS臨時授權訪問OSS 的配置
- 安裝 Nuget
dotnet add package aliyun-net-sdk-core
dotnet add package aliyun-net-sdk-sts
dotnet add package Aliyun.OSS.SDK.NetCore
- 代碼參考案例
class Program
{
static void Main(string[] args)
{
var bucketName = "<your bucket>";
var accessKeyId = "<your accessKeyId>";
var accessKeySecret = "<your accessKeySecret>";
var endpoint = "<your endpint>";
var region = "<your region>";
var roleArn = "<your roleArn>"; // 通過阿里雲RAM管理角色管理可以拿到
var roleSessionName = "xxx"; // 隨機指定一個即可
var objectName = "test.txt";
IClientProfile profile =
DefaultProfile.GetProfile(region, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
AssumeRoleRequest request = new AssumeRoleRequest();
request.AcceptFormat = FormatType.JSON;
//指定角色ARN
request.RoleArn = roleArn;
request.RoleSessionName = roleSessionName;
request.DurationSeconds = 3600;
request.Policy = BuildPolicy(bucketName, "avatars"); // 配置對應的權限
AssumeRoleResponse response = client.GetAcsResponse(request);
Console.WriteLine("AccessKeyId: " + response.Credentials.AccessKeyId);
Console.WriteLine("AccessKeySecret: " + response.Credentials.AccessKeySecret);
Console.WriteLine("SecurityToken: " + response.Credentials.SecurityToken);
Console.WriteLine("Expiration: " + DateTime.Parse(response.Credentials.Expiration).ToLocalTime());
var ossClient = new OssClient(endpoint, response.Credentials.AccessKeyId,
response.Credentials.AccessKeySecret,
response.Credentials.SecurityToken);
try
{
byte[] binaryData = Encoding.ASCII.GetBytes("test");
MemoryStream requestContent = new MemoryStream(binaryData);
// 上傳文件。
ossClient.PutObject(bucketName, $"{bucketName}/{objectName}", requestContent);
Console.WriteLine("Put object succeeded");
}
catch (Exception ex)
{
Console.WriteLine("Put object failed, {0}", ex.Message);
}
}
public static string BuildPolicy(string bucket, string dir)
{
return "{\n" +
" \"Version\": \"1\", \n" +
" \"Statement\": [\n" +
" {\n" +
" \"Action\": [\n" +
" \"oss:PutObject\"\n" +
" ], \n" +
" \"Resource\": [\n" +
$" \"acs:oss:*:*:{bucket}/{dir}/*\" \n" +
" ], \n" +
" \"Effect\": \"Allow\"\n" +
" }\n" +
" ]\n" +
"}";
}
}
可以修改 BuildPolicy
里面的 Json 動態配置,以上配置了客戶端拿到訪問憑據后,只能上傳文件到指定目錄,沒有其他權限了。其次訪問STS服務拿到的 AccessKeyId
與 AccessKeySecret
都是臨時與我們阿里雲RAM控制面板拿到的是不一樣的。這樣就無須擔心我們 AccessKeyId
與 AccessKeySecret
泄露以及訪問權限的問題。
End
服務端頒發授權憑證,客戶端直傳 OSS 應該是目前的最佳實踐,后面再配合回調地址,可以更好的貼近實際場景。但是回調地址必須是公網可訪問的,這里就沒整了。直傳 OSS 比之前中轉節省時間,也不需要占用額外的服務器資源。
- 原文地址:鏈接 本文收錄在個人博客 https://gridea.run,歡迎來踩