今天我花了一些时间在C#中查看各种HMAC实现,以用于即将到来的WebAPI项目。我想从一些现有代码开始,只是为了看到它在我从头开始编写或根据我的需要修改它之前更好地理解它。
这里和网上都有很多很棒的文章和帖子。但是,我已经到了需要一些指针的地步,并且非常欣赏一些见解。
我从Cuong的帖子开始:How to secure an ASP.NET Web API。
我知道我必须扩展它,因为我想支持json和formencoded数据。我的测试客户端也使用HttpClient用C#编写,我启动了一个空的WebAPI项目并使用了ValuesController。
以下是我的观察和问题:
POSTing:为了让Cuong的代码工作(验证成功),我的POST需要在URL中包含参数,但是为了将值传递给我的控制器,我需要将它们包含在身体。这种认证是正常的吗?在此特定实例中,我正在散列的消息是http://:10300 / api / values?param1 = value1& param2 = value2。现在我可以手动解析查询字符串以获取它们,但是为了通过绑定将值传递给我的控制器,我还必须:
var dict = new Dictionary<string, string>
{
{"param1", "value1"},
{"param2", "value2"}
};
var content = new FormUrlEncodedContent(dict);
var response = await httpClient.PostAsync(httpClient.BaseAddress, content);
否则我的参数在ValuesController的post动作中始终为null。
我打算扩展代码以包含一个nonce。在nonce,时间戳和动词的组合之间,是否足够安全哈希?是否真的需要散列消息?
我尝试(非常不成功)扩展代码以支持json以及表单编码数据,我必须遗漏一些明显的东西。
Cuong正在使用Authentication和Timestamp标头,而不是将签名和时间戳放在查询字符串中。一种方法比另一种方法有益处吗?我读过的大多数文章都在查询字符串中包含它们。
代码看起来很棒,我在这里有点偏离我的元素。我可能会更安全(saner?)只是从头开始写它以欣赏它的细微差别。也就是说,如果有人能够对我所看到的内容有所了解,那就太棒了。
在一天结束时,我希望能够使用WebAPI框架的内置授权机制来简单地归因于方法/控制器,能够接受表单编码和json数据以及合理地为复杂类型建模绑定
*更新*
我今天做了一些工作,下面是我的nUnit PostTest中的代码。我想出了如何在不将它们包含在正文和查询字符串(下面的代码)中的情况下获取值。
[Test]
public async void PostTest()
{
using (var httpClient = new HttpClient())
{
var payload = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"key1", "value1"},
{"key2", "value2"}
});
var now = DateTime.UtcNow.ToString("U");
httpClient.BaseAddress = new Uri(string.Format("http://ipv4.fiddler:10300/api/values"));
httpClient.DefaultRequestHeaders.Add("Timestamp", now);
httpClient.DefaultRequestHeaders.Add("Authentication", string.Format("test:{0}", BuildPostMessage(now, httpClient.BaseAddress, await payload.ReadAsStringAsync())));
var response = await httpClient.PostAsync(httpClient.BaseAddress, payload);
await response.Content.ReadAsStringAsync();
Assert.AreEqual(true, response.IsSuccessStatusCode);
}
}
我还想出了它的模型绑定部分。这里有一篇很棒的文章:http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data解释了POST是如何工作的,我能够使用我自己设计的模型以及FormDataCollection对象。
现在我想知道是否值得添加json编码的消息,或者是否需要在FormUrlEncoding上进行标准化。此外,客户端是否已经足够,或者我应该实施服务器端nounce?服务器端是否将所有对服务的调用加倍(第一个抛出401,第二个包含带有nounce的有效负载?