我正在使用C#将数据发送到Azure事件中心。与Eventhub客户端不同,数据将通过http发布。根据要求,我可以创建一个嵌入在http头中的SAStoken。但是在发布时我得到501,未经授权的访问错误。不知道我哪里错了。这是我写的代码
public static async Task<HttpResponseMessage> SendDataUsingHttp()
{
// Namespace info.
var serviceNamespace = "myeventhubs";
var hubName = "eventhub1";
var url = string.Format("{0}/publishers/{1}/messages", hubName, 1);
//var url = string.Format("{0}/messages", hubName);
var baseUri = new
Uri(string.Format("https://{0}.servicebus.windows.net/"
, serviceNamespace));
var SharedAccessKeyName = "All";
var SharedAccessKey = "<shared access key>";
var sasToken =
createSasToken(baseUri.ToString(),SharedAccessKeyName,
SharedAccessKey);
var evtData = new
{
Temperature = new Random().Next(20, 50)
};
var payload = JsonConvert.SerializeObject(evtData);
// Create client.
var httpClient = new HttpClient
{
BaseAddress = baseUri
};
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue
("SharedAccessSignature", sasToken);
var content = new StringContent(payload, Encoding.UTF8);
content.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
HttpResponseMessage result = null;
try
{
result = await httpClient.PostAsync(url, content);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return result;
}
private static string createSasToken(string baseUri, string keyName,
string key)
{
TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
var week = 60 * 60 * 24 * 7;
var expiration = Convert.ToString((int)sinceEpoch.TotalSeconds +
week);
string stringToSign = HttpUtility.UrlEncode(baseUri) + "\n" +
expiration;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)); //--
var signature =
Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(
stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture,
"SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
HttpUtility.UrlEncode(baseUri), HttpUtility.UrlEncode(signature),
expiration, keyName);
return sasToken;
}
结果
{StatusCode:401,ReasonPhrase:'Unauthorized',版本:1.1, 内容:System.Net.Http.StreamContent,Headers:{ 传输编码:分块严格传输 - 安全: max-age = 31536000日期:太阳,2018年6月17日08:35:43 GMT服务器: Microsoft-HTTPAPI / 2.0 Content-Type:application / xml;字符集= UTF-8
内容:{System.Net.Http.StreamContent}标题: {Transfer-Encoding:chunked Strict-Transport-Security: max-age = 31536000日期:太阳,2018年6月17日08:35:43 GMT服务器: 微软HTTPAPI / 2.0
答案 0 :(得分:0)
根据您的createSasToken
方法,它将使用以下格式生成授权标头值:
Authorization: SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}
对于您的请求,您还需指定以下代码:
System.Net.Http.Headers.AuthenticationHeaderValue("SharedAccessSignature", sasToken);
使用Fiddler捕获网络跟踪,您会发现发送的请求中的授权标头值如下所示:
Authorization: SharedAccessSignature SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}
对于您的代码,您需要在sasToken
方法下调整createSasToken
的格式。
此外,baseUri
方法的createSasToken
参数必须是您请求的完整请求路径。因此,您需要修改SendDataUsingHttp
下的相关代码,以生成令牌,如下所示:
var sasToken =createSasToken(baseUri+url, SharedAccessKeyName, SharedAccessKey);