阿里雲OSS-web端直傳的服務端簽名算法


web直傳的好處:用戶通過瀏覽器直接上傳到阿里雲OSS,對web服務器沒有壓力!

這里的服務端代碼僅僅用來計算簽名,不處理上傳!如果.net服務端直傳(支持分片和斷點續傳),參考OSS .NET SDK(https://help.aliyun.com/document_detail/32090.html)

WEB端表單上傳,需要簽名域Signature,通過js計算簽名,AccessKeyID和AcessKeySecret會暴露在前端頁面,嚴重安全隱患,因此用服務端計算簽名再返回給瀏覽器,瀏覽器通過表單(multipart/form-data 編碼)的方式就可以直接上傳文件到OSS了,

 

阿里官網文檔https://help.aliyun.com/document_detail/31926.html (Java,Python,PHP,Go,Ruby簽名示例)沒有提供C#版本的簽名計算代碼,這里提供一個供參考

PostObject API參考: https://help.aliyun.com/document_detail/31988.html

什么是Post Policy?

Post請求的policy表單域用於驗證請求的合法性。 policy為一段經過UTF-8和base64編碼的JSON文本,聲明了Post請求必須滿足的條件。

Policy表單域的示例 (JSON格式)

{ "expiration": "2014-12-01T12:00:00.000Z","conditions": [{"bucket": "johnsmith" },["starts-with", "$key", "user/eric/"]]}

注意:Post policy中必須包含expiration和condtions。

什么是Post Signature

Post請求的Signature表單域是根據Policy計算的

計算Signature的具體流程為

  1. 創建一個 UTF-8 編碼的 policy。
  2. 將 policy 進行 base64 編碼,其值即為 policy 表單域該填入的值,將該值作為將要簽名的字符串。
  3. 使用 AccessKeySecret 對要簽名的字符串進行簽名。

 

 C#簽名代碼(MVC)

前提:需要安裝aliyun.oss.sdk和Newtonsoft.Json的nuget包

 public class AliyunController : MyControllerBase
    {
        public string accessKeyId = System.Configuration.ConfigurationManager.AppSettings["aliyun_ak_id"];//請填寫您的AccessKeyId。
        public string accessKeySecret = System.Configuration.ConfigurationManager.AppSettings["aliyun_ak_secret"];//請填寫您的AccessKeySecret
        public string bucket = System.Configuration.ConfigurationManager.AppSettings["aliyun_bucket"];//請填寫您的bucket name
        // GET: Aliyun
        public ContentResult GetPostObjectSignature(int courseId)
        {
            string host = "http://"+ bucket + ".oss-cn-shanghai.aliyuncs.com";//請填寫您的bucket endpoint。

            const string endpoint = "http://oss-cn-shanghai.aliyuncs.com";//請填寫您的endpoint

            //第一步,構造policy
            var dir = "zhangsan/";//設置當前用戶上傳指定的前綴,必須以斜線結尾,類似目錄(OSS不存在多級目錄,但是可以模擬)
            var expiration = DateTime.Now.AddMinutes(100);
            var policyConds = new PolicyConditions();
            policyConds.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, dir);//上傳目錄
            policyConds.AddConditionItem(PolicyConditions.CondContentLengthRange, 1, 1048576000);//允許上傳的文件大小限制       
        var ossClient = new OssClient(endpoint, accessKeyId, accessKeySecret);//調用阿里雲SDK的API
        var postPolicy = ossClient.GeneratePostPolicy(expiration, policyConds);//給policyConds添加過期時間並json序列化(格式iso8601:"yyyy-MM-dd'T'HH:mm:ss.fff'Z'")

            /*生成的Policy范例
                {"expiration":"2017-05-17T20:23:23Z","conditions":[["content-length-range",0,1048576000],["starts-with","$key","zhangsan"]]}
                */
            //第二步 將policy 的json字符串進行base64編碼

            var base64Policy = Convert.ToBase64String(Encoding.UTF8.GetBytes(postPolicy));

            //第三步,生成簽名(哈希算法)
            var signature = ComputeSignature(accessKeySecret, base64Policy);//生成簽名
            
             //以下返回給前端表單域或者阿里雲OSS的js api
            TimeSpan ts = expiration - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            var expire = Convert.ToInt64(ts.TotalSeconds);

            Dictionary<string, object> response_dic = new Dictionary<string, object>();
            response_dic["accessid"] = accessKeyId;
            response_dic["host"] = host;
            response_dic["policy"] = base64Policy;
            response_dic["signature"] = signature;
            response_dic["expire"] = expire;
            //這個參數是設置用戶上傳指定的前綴
            response_dic["dir"] = dir;
            return Content(JsonConvert.SerializeObject(response_dic));
        }
      private string ComputeSignature(string key, string data)
        {
            using (var algorithm = KeyedHashAlgorithm.Create("HmacSHA1".ToUpperInvariant()))
            {
                algorithm.Key = Encoding.UTF8.GetBytes(key.ToCharArray());
                return Convert.ToBase64String(
                    algorithm.ComputeHash(Encoding.UTF8.GetBytes(data.ToCharArray())));
            }
        }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM