所以我们想使用一个在 ASP.net 中构建并使用 OData 作为协议的 webapi。我做了一些功课,发现微软有一个非常好的文档OData Connected Service
。我唯一找不到的是我们要使用的 webapi 具有 HMAC 以确保安全。我找不到OData Connected Service
与 HMAC 一起使用的示例。有人可以解释 HMAC 是否以及如何使用OData Connected Service
?
问问题
156 次
1 回答
1
可能答案取决于服务器端 HMAC 的具体实现。
如果服务器接收到请求中包含的所有数据以及Authorization标头,并从Authorization标头中提取值(APP Id、Signature、Nonce和Request Time stamp),则客户端应该:
通过组合将要发送的所有数据构建一个字符串,该字符串包含以下参数(APP Id、HTTP 方法、请求 URI、请求时间戳、nonce和请求负载的 Base 64 字符串表示)。
签名将使用自定义方案(例如“amx” )在Authorization标头中发送。Authorization 标头中的数据将包含APP Id、请求时间戳和由冒号“:”分隔的nonce 。授权标头的格式类似于:[Authorization: amx APPId:Signature:Nonce:Timestamp]。
客户端像往常一样发送请求以及Authorization标头中生成的数据(只需使用客户端挂钩或httpclient)。
示例(生成客户端代码后):
private string APPId = "65d3a4f0-0239-404c-8394-21b94ff50604";
private string APIKey = "WLUEWeL3so2hdHhHM5ZYnvzsOUBzSGH4+T3EgrQ91KI=";
public async Task<IEnumerable<string>> TestODataHMAC()
{
// add there your OData Uri
var container = new DefaultContainer(new Uri("https://services.odata.org/V4/(S(qc322lduoxrqt13nhydbdcvx))/TripPinServiceRW/"));
container.Configurations.RequestPipeline.OnMessageCreating = (args) =>
{
var request = new HttpWebRequestMessage(args);
// Get the Request URI
string requestUri = HttpUtility.UrlEncode(request.Url.AbsoluteUri.ToLower());
// Calculate UNIX time
var epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
var timeSpan = DateTime.UtcNow - epochStart;
var requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString();
// Create the random nonce for each request
var nonce = Guid.NewGuid().ToString();
// Creating the raw signature string by combinging
// APPId, request Http Method, request Uri, request TimeStamp, nonce
var signatureRawData = string.Format("{0}{1}{2}{3}{4}", APPId, request.Method, requestUri, requestTimeStamp, nonce);
// Converting the APIKey into byte array
var secretKeyByteArray = Convert.FromBase64String(APIKey);
// Converting the signatureRawData into byte array
var signature = Encoding.UTF8.GetBytes(signatureRawData);
// Generate the hmac signature and set it in the Authorization header
using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray))
{
var signatureBytes = hmac.ComputeHash(signature);
var requestSignatureBase64String = Convert.ToBase64String(signatureBytes);
//Setting the values in the Authorization header using custom scheme (hmacauth)
request.SetHeader("Authorization", string.Format("hmacauth {0}:{1}:{2}:{3}", APPId, requestSignatureBase64String, nonce, requestTimeStamp));
}
return request;
};
// add there your OData method call
var nquery = container.People.Where(p => p.Gender == PersonGender.Female).Take(10) as DataServiceQuery<Person>;
var response = await nquery?.ExecuteAsync();
return (response as QueryOperationResponse<Person>).Select(p => p.FirstName).ToArray();
}
于 2019-10-14T08:35:29.563 回答