如何保护 ASP.NET Web API
如何保护 ASP.NET Web API
已关闭。这个问题需要更多的关注点。它目前不接受回答。
想要改进这个问题吗?通过编辑此帖子将问题聚焦在一个问题上更新问题。
改进这个问题
我想使用ASP.NET Web API构建一个 RESTful Web服务,第三方开发人员将使用它来访问我应用的数据。
我已经阅读了很多关于OAuth的内容,它似乎是标准,但是找到一个好的带有文档解释其工作原理的示例(并且确实可行!)似乎非常困难(特别是对于OAuth的新手来说)。
是否有一个可以实际构建,工作并显示如何实现它的示例?
我下载了很多示例:
- DotNetOAuth-从新手的角度来看,文档是无望的。
- Thinktecture-无法构建。
我还看了一些博客,提出了一种简单的基于令牌的方案(比如这个),这似乎是重新发明轮子,但它的概念相当简单。
似乎在SO上有很多类似的问题,但没有好的答案。
大家在这个领域都在做什么?
我建议首先从最简单的解决方案开始 - 在你的情况下,使用简单的HTTP基本认证+HTTPS可能已经足够了。
如果不行(例如您不能使用https,或需要更复杂的密钥管理),您可以像其他人建议的那样查看基于HMAC的解决方案。这种API的一个很好的例子是亚马逊S3(http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html)。
我写了一篇关于ASP.NET Web API中基于HMAC的身份验证的博客文章。它涵盖了Web API服务和Web API客户端,代码可在bitbucket上获得(http://www.piotrwalat.net/hmac-authentication-in-asp-net-web-api/)。
这是有关Web API中基本身份验证的文章:http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/
请记住,如果您将向第三方提供API,您还可能需要负责提供客户端库。基本身份验证在这里具有显着优势,因为它在大多数编程平台上都可以直接使用。另一方面,HMAC并没有那么标准化,需要自定义实现。这些可能相对简单,但仍需要工作。
PS. 还有一种使用HTTPS +证书的选项。http://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/
更新:
我已经将这个链接添加到我的另一个回答如何为ASP.NET Web API使用JWT身份验证中,供任何对JWT感兴趣的人使用。
我们已经成功地将HMAC身份验证应用于安全的Web API,并且它工作得很好。 HMAC身份验证对于每个消费者都使用一个密钥,消费者和服务器都知道它以 HMAC256 哈希一条消息,通常使用消费者的哈希密码作为密钥。
消息通常是从HTTP请求中的数据构建的,甚至是添加到HTTP标头中的自定义数据,消息可能包括:
- 时间戳:请求发送的时间(UTC或GMT)
- HTTP动词:GET,POST,PUT,DELETE。
- POST数据和查询字符串,
- URL
在幕后,HMAC身份验证将是:
消费者向web服务器发送HTTP请求,在构建签名(hmac哈希输出)后,HTTP请求的模板:
User-Agent: {agent} Host: {host} Timestamp: {timestamp} Authentication: {username}:{signature}
GET请求的示例:
GET /webapi.hmac/api/values User-Agent: Fiddler Host: localhost Timestamp: Thursday, August 02, 2012 3:30:32 PM Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
哈希消息以获得签名:
GET\n Thursday, August 02, 2012 3:30:32 PM\n /webapi.hmac/api/values\n
POST请求的示例,带有查询字符串(签名下面不正确,只是一个示例)
POST /webapi.hmac/api/values?key2=value2 User-Agent: Fiddler Host: localhost Content-Type: application/x-www-form-urlencoded Timestamp: Thursday, August 02, 2012 3:30:32 PM Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw= key1=value1&key3=value3
哈希消息以获得签名:
GET\n Thursday, August 02, 2012 3:30:32 PM\n /webapi.hmac/api/values\n key1=value1&key2=value2&key3=value3
请注意,表单数据和查询字符串应按顺序排列,因此服务器上的代码会获取查询字符串和表单数据以构建正确的消息。
当HTTP请求到达服务器时,实施身份验证操作筛选器来解析请求以获取信息:HTTP动词、时间戳、URI、表单数据和查询字符串,然后根据这些使用服务器上的密钥(哈希密码)构建签名(使用hmac哈希)。
从请求中获取用户名,然后从数据库获取密钥。
然后服务器代码比对请求中的签名和构建的签名。如果相等,鉴权通过,否则失败。
构建签名的代码:
private static string ComputeHash(string hashedPassword, string message) { var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper()); string hashString; using (var hmac = new HMACSHA256(key)) { var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message)); hashString = Convert.ToBase64String(hash); } return hashString; }
那么,如何防止重放攻击?
为时间戳添加约束条件,类似于:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(server time:请求到达服务器的时间)
同时,在内存中缓存请求的签名(使用MemoryCache,应该保持在时间限制内)。如果下一个请求带有与先前请求相同的签名,则将其拒绝。