using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace RC.Domain
{
/// <summary>
/// Aliyun接口签名算法,以调用域名接口为例,调用方式见下面代码
/// 注意事项:
/// 1.AccessKeyId和AccessKeySecret,在阿里云控制台查看。
/// 2.注意接口Version和接口地址,不同接口的版本和请求地址是不一样的。
/// 参考:https://help.aliyun.com/document_detail/42884.html?spm=a2c4g.11186623.6.767.7ea976dbSQ3DnF
/// </summary>
public class AliyunHelper
{
//【调用方式】
//var parameters = new Dictionary<string, string>
//{
// {"Action", "DescribeDomainRecords"},
// {"DomainName", "qingshanboke.com"}
//};
//var helper = new AliyunHelper("alidns.aliyuncs.com", parameters)
//{
// AccessKeyId = txtAppKey.Text,
// AccessKeySecret = txtSecret.Text,
// Version = "2015-01-09"
//};
//var result = helper.DoRequest();
//txtLog.Text = result;
private readonly Dictionary<string, string> _parameters;
/// <summary>
/// 阿里云颁发给用户的访问服务所用的密钥ID
/// </summary>
public string AccessKeyId = "****************";
/// <summary>
/// 阿里云颁发给用户的访问服务所用的密钥
/// </summary>
public string AccessKeySecret = "******************";
public string ApiUrl;
/// <summary>
/// 返回值的类型,支持JSON与XML。默认为XML
/// </summary>
public string Format = "JSON";
/// <summary>
/// API版本号,为日期形式:YYYY-MM-DD,本版本对应为2016-05-11
/// </summary>
public string Version = "2016-05-11";
public AliyunHelper(string apiUrl, Dictionary<string, string> parameters)
{
ApiUrl = apiUrl;
_parameters = parameters;
}
/// <summary>
/// 签名结果串
/// </summary>
public string Signature { get; set; }
private void BuildParameters()
{
_parameters.Add("Format", Format.ToUpper());
_parameters.Add("Version", Version);
_parameters.Add("AccessKeyId", AccessKeyId);
_parameters.Add("SignatureVersion", "1.0");
_parameters.Add("SignatureMethod", "HMAC-SHA1");
_parameters.Add("SignatureNonce", Guid.NewGuid().ToString());
_parameters.Add("Timestamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"));
}
public void ComputeSignature()
{
BuildParameters();
var canonicalizedQueryString = string.Join("&",
_parameters.OrderBy(x => x.Key).Select(x => PercentEncode(x.Key) + "=" + PercentEncode(x.Value)));
var stringToSign = "GET&" + PercentEncode("/") + "&" + PercentEncode(canonicalizedQueryString);
var keyBytes = Encoding.UTF8.GetBytes(AccessKeySecret + "&");
var hmac = new HMACSHA1(keyBytes);
var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
Signature = Convert.ToBase64String(hashBytes);
_parameters.Add("Signature", Signature);
}
public static string PercentEncode(string value)
{
return UpperCaseUrlEncode(value)
.Replace("+", "%20")
.Replace("*", "%2A")
.Replace("/", "%2F")
.Replace("%7E", "~");
}
private static string UpperCaseUrlEncode(string s)
{
var temp = HttpUtility.UrlEncode(s).ToCharArray();
for (var i = 0; i < temp.Length - 2; i++)
if (temp[i] == '%')
{
temp[i + 1] = char.ToUpper(temp[i + 1]);
temp[i + 2] = char.ToUpper(temp[i + 2]);
}
return new string(temp);
}
public string DoRequest()
{
ComputeSignature();
var host = ApiUrl.ToLower().StartsWith("http") ? ApiUrl : "http://" + ApiUrl;
host = host.TrimEnd('/');
var url = host + "/?" +
string.Join("&", _parameters.OrderBy(x => x.Key).Select(x => x.Key + "=" + HttpUtility.UrlEncode(x.Value)));
return HttpGet(url);
}
public static string HttpGet(string url)
{
try
{
var request = (HttpWebRequest)WebRequest.Create(url);
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
var stream = response.GetResponseStream();
string s = null;
if (stream != null)
{
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
s = reader.ReadToEnd();
reader.Close();
}
stream.Close();
}
return s;
}
return "请求 " + url + " 报错:" + response.StatusCode;
}
}
catch (WebException ex)
{
var response = (HttpWebResponse)ex.Response;
if (response.StatusCode == HttpStatusCode.BadRequest)
{
using (Stream data = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
return text;
}
}
}
return "请求 " + url + " 报错:" + response.StatusCode + " " + ex.Message;
}
}
}
}