我正在尝试将文章发布到 Apple News API,但出现以下错误:
未经授权的错误(错误签名)。
Apple 指示执行以下操作:
将请求的规范版本创建为以下内容的逐字节串联:
HTTP 方法(例如,GET 或 POST,全部大写)
请求的完整 URL
ISO 8601 格式的当前日期 如果请求是 POST 请求并且它包含一个实体,请包含以下内容:
Content-Type 标头的值
实体的全部内容
将 API 密钥的秘密从 Base64 解码为原始字节。使用 HMAC SHA-256 在规范请求上使用解码的 API 密钥创建散列。使用 Base64 对哈希进行编码。将授权标头设置为:
授权:HHMAC;键=; 签名=; date= 其中是步骤 1 中的日期字符串。发送请求。
下面是我的 C# 代码:
string path = "https://news-api.apple.com/channels/channelid/articles";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(path);
httpWebRequest.ContentType = "multipart/form-data";
httpWebRequest.Method = "POST";
httpWebRequest.Accept = "application / json";
httpWebRequest.Host = "news-api.apple.com";
httpWebRequest.UseDefaultCredentials = true;
httpWebRequest.PreAuthenticate = true;
httpWebRequest.ProtocolVersion = HttpVersion.Version11;
httpWebRequest.KeepAlive = true;
string appleDate= String.Format("{0}Z", DateTime.UtcNow.ToString("s"));
string credentials = String.Format("{0}:{1}", "Content-Disposition", "form-data; ");
credentials += String.Format("{0}:{1}", "filename", "article.json; ");
credentials += String.Format("{0}:{1}", "name", "article.json; ");
credentials += String.Format("{0}:{1}", "Authorization", "HHMAC; ");
credentials += String.Format("{0}:{1}", "key", "api key; ");
string decodedSecret = base64Decode("secret_key");
string canonical_request = "POST" + path + appleDate;
string hash = Class1.HmacSha256Digest(canonical_request, decodedSecret);
string Encodedhash = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(hash));
credentials += String.Format("{0}:{1}", "signature", Encodedhash + "; ");
credentials += String.Format("{0}:{1}", "date", appleDate + "; ");
httpWebRequest.Headers.Add("Authorization", "Basic " +credentials);
httpWebRequest.Credentials = new NetworkCredential("xxx.com", "xxxx");
using (StreamReader r = new StreamReader(HttpContext.Current.Server.MapPath("~/article.json")))
{
string json = r.ReadToEnd();
dynamic jsonObj = JsonConvert.DeserializeObject(json);
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(json);
Stream newStream = httpWebRequest.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = newStreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
解码方法:
public static string base64Decode(string data)
{
var base64EncodedBytes = System.Convert.FromBase64String(data);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
HmacSha256扩展方法:
public static class Class1
{
public static string HmacSha256Digest(this string message, string secret)
{
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] keyBytes = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
System.Security.Cryptography.HMACSHA256 cryptographer = new System.Security.Cryptography.HMACSHA256(keyBytes);
byte[] bytes = cryptographer.ComputeHash(messageBytes);
return BitConverter.ToString(bytes).Replace("-", "").ToLower();
}
}
我有一个
未经授权的错误(错误签名)。