本文以.NET语言为例,介绍如何在服务端完成签名,并设置上传回调,然后通过表单直传数据到OSS。
前提条件
- 应用服务器对应的域名可通过公网访问。
- 应用服务器已安装Visual Studio 2012或更高版本。
- 应用服务器已经安装.Net Framework 4.5及以上版本。
步骤1:配置应用服务器
- 下载应用服务器源码(.NET版本)。
- 本示例中以Windows环境为例,将下载的文件解压到C:\callback-server-dotnet目录下。
- 进入该目录,找到并打开源码文件TinyHttpServer.cs,修改如下的代码片段:
// 请填写您的AccessKeyId。 public static string accessKeyId = ""; // 请填写您的AccessKeySecret。 public static string accessKeySecret = ""; // host的格式为https://bucketname.endpoint,请替换为您的真实信息。 public static string host = "https://bucketname.oss-cn-hangzhou.aliyuncs.com"; // callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。 public static string callbackUrl = "http://192.168.0.1:8888"; // 用户上传文件时指定的前缀。 public static string uploadDir = "user-dir-prefix/";
- accessKeyId:设置您的AccessKeyId。
- accessKeySecret:设置您的AessKeySecret。
- host:格式为https://bucketname.endpoint,例如https://bucket-name.oss-cn-hangzhou.aliyuncs.com。关于Endpoint的介绍,请参见Endpoint访问域名。
- callbackUrl:设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。本例中修改为:
String callbackUrl ="http://10.10.10.10:1234";
。 - uploadDir:设置上传到OSS文件的前缀,以便于区分文件。您也可以填写空值。
- 使用Visual Studio打开aliyun-oss-net-callback-server.sln工程文件,单击启动,生成执行程序aliyun-oss-net-callback-server.exe。
步骤2:配置客户端
- 下载客户端源码。
- 将文件解压,本例中以解压到
D:\aliyun\aliyun-oss-appserver-js
目录为例。 - 进入该目录,打开
upload.js
文件,找到下面的代码语句:// serverUrl是用户获取签名和Policy等信息的应用服务器的URL,请将下面的IP和Port配置为您自己的真实信息。 serverUrl = 'http://192.168.0.1:8888'
- 将
severUrl
改成应用服务器的地址,客户端可以通过它获取签名直传Policy等信息。例如本示例中可修改为:serverUrl = 'http://10.10.10.10:1234'
。
步骤3:修改CORS
客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin
的请求消息。OSS对带有Origin
头的请求消息会进行跨域规则(CORS)的验证。因此需要为Bucket设置跨域规则以支持Post方法。
- 登录OSS管理控制台。
- 单击Bucket列表,然后单击目标Bucket名称。
- 在左侧导航栏,选择数据安全 > 跨域设置。
- 单击创建规则,配置如下图所示。
说明 为了您的数据安全,实际使用时,
来源建议填写实际允许访问的域名。更多配置信息请参见
设置跨域访问。
步骤4:体验上传回调
- 启动应用服务器。
在应用服务器的命令行窗口下,进入到
aliyun-oss-net-callback-server.exe执行程序生成的目录下,执行命令
aliyun-oss-net-callback-server.exe ${ip} ${port}启动应用服务器。cd C:\Users\Desktop\callback-server-dotnet\aliyun-oss-net-callback-server\bin\Debug\ aliyun-oss-net-callback-server.exe 10.10.10.10 1234
说明
- 程序目录以实际环境为准。您在使用Visual Studio生成aliyun-oss-net-callback-server.exe程序时,可以看到程序目录。
- ${ip}和${port} 修改成配置应用服务器的IP和端口。例如本示例中为aliyun-oss-net-callback-server.exe 10.10.10.10 1234。
- 启动客户端。
- 在PC端的客户端源码目录中,打开index.html文件。
重要 index.html文件不保证兼容IE 10以下版本浏览器,若使用IE 10以下版本浏览器出现问题时,您需要自行调试。
- 单击选择文件,选择指定类型的文件,单击开始上传。
上传成功后,显示回调服务器返回的内容。
- 在PC端的客户端源码目录中,打开index.html文件。
应用服务器核心代码解析
应用服务器源码包含了签名直传服务和上传回调服务两个功能。
- 签名直传服务响应客户端发送给应用服务器的GET消息,代码片段如下:
private static string GetPolicyToken() { //expireTime var expireDateTime = DateTime.Now.AddSeconds(expireTime); // example of policy //{ // "expiration": "2020-05-01T12:00:00.000Z", // "conditions": [ // ["content-length-range", 0, 1048576000] // ["starts-with", "$key", "user-dir-prefix/"] // ] //} //policy var config = new PolicyConfig(); config.expiration = FormatIso8601Date(expireDateTime); config.conditions = new List<List
- 上传回调服务响应OSS发送给应用服务器的POST消息,代码片段如下:
public bool VerifySignature() { // Get the Authorization Base64 from Request if (this.httpHeadersDict["authorization"] != null) { this.strAuthorizationRequestBase64 = this.httpHeadersDict["authorization"].ToString(); } else if (this.httpHeadersDict["Authorization"] != null) { this.strAuthorizationRequestBase64 = this.httpHeadersDict["Authorization"].ToString(); } if (this.strAuthorizationRequestBase64 == "") { Console.WriteLine("authorization property in the http request header is null. "); return false; } // Decode the Authorization from Request this.byteAuthorizationRequest = Convert.FromBase64String(this.strAuthorizationRequestBase64); // Decode the URL of PublicKey this.strPublicKeyURLBase64 = this.httpHeadersDict["x-oss-pub-key-url"].ToString(); var bytePublicKeyURL = Convert.FromBase64String(this.strPublicKeyURLBase64); var strAsciiPublickeyURL = System.Text.Encoding.ASCII.GetString(bytePublicKeyURL); // Get PublicKey from the URL ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(validateServerCertificate); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strAsciiPublickeyURL); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader srPublicKey = new StreamReader(response.GetResponseStream(), Encoding.UTF8); this.strPublicKeyBase64 = srPublicKey.ReadToEnd(); response.Close(); srPublicKey.Close(); this.strPublicKeyContentBase64 = this.strPublicKeyBase64.Replace("-----BEGIN PUBLIC KEY----- ", "").Replace("-----END PUBLIC KEY-----", "").Replace(" ", ""); this.strPublicKeyContentXML = this.RSAPublicKeyString2XML(this.strPublicKeyContentBase64); // Generate the New Authorization String according to the HttpRequest String[] arrURL; if (this.httpURL.Contains('?')) { arrURL = this.httpURL.Split('?'); this.strAuthSourceForMD5 = String.Format("{0}?{1} {2}", System.Web.HttpUtility.UrlDecode(arrURL[0]), arrURL[1], this.httpBody); } else { this.strAuthSourceForMD5 = String.Format("{0} {1}", System.Web.HttpUtility.UrlDecode(this.httpURL), this.httpBody); } // MD5 hash bytes from the New Authorization String var byteAuthMD5 = byteMD5Encrypt32(this.strAuthSourceForMD5); // Verify Signature System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); try { RSA.FromXmlString(this.strPublicKeyContentXML); } catch (System.ArgumentNullException e) { throw new ArgumentNullException(String.Format("VerifySignature Failed : RSADeformatter.VerifySignature get null argument : {0} .", e)); } catch (System.Security.Cryptography.CryptographicException e) { throw new System.Security.Cryptography.CryptographicException(String.Format("VerifySignature Failed : RSA.FromXmlString Exception : {0} .", e)); } System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA); RSADeformatter.SetHashAlgorithm("MD5"); var bVerifyResult = false; try { bVerifyResult = RSADeformatter.VerifySignature(byteAuthMD5, this.byteAuthorizationRequest); } catch (System.ArgumentNullException e) { throw new ArgumentNullException(String.Format("VerifySignature Failed : RSADeformatter.VerifySignature get null argument : {0} .", e)); } catch (System.Security.Cryptography.CryptographicUnexpectedOperationException e) { throw new System.Security.Cryptography.CryptographicUnexpectedOperationException(String.Format("VerifySignature Failed : RSADeformatter.VerifySignature Exception : {0} .", e)); } return bVerifyResult; } public void DoPost() { this.GetPostBody(); // Verify Signature try { if (this.VerifySignature()) { Console.WriteLine(" VerifySignature Successful . "); // do something accoding to callback_body ... this.HttpResponseSuccess(); } else { Console.WriteLine(" VerifySignature Failed . "); this.HttpResponseFailure(); } } catch { Console.WriteLine(" VerifySignature Failed . "); this.HttpResponseFailure(); } }
内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家
阿里云企业补贴进行中: 马上申请
腾讯云限时活动1折起,即将结束: 马上收藏
同尘科技为腾讯云授权服务中心。
购买腾讯云产品享受折上折,更有现金返利:同意关联,立享优惠
转转请注明出处:https://www.yunxiaoer.com/158684.html