我想使用ASP.NET Web API构建一个 RESTful Web服务,第三方开发人员将使用它来访问我的应用程序的数据 .
我已经阅读了很多关于 OAuth 的内容,它似乎是标准的,但找到一个很好的样本,文档解释它是如何工作的(实际上确实有效!)似乎非常困难(特别是对于OAuth的新手) .
是否有实际构建和工作的示例,并说明如何实现它?
我已经下载了很多样本:
-
DotNetOAuth - 从新手的角度来看,文档是没有希望的
-
Thinktecture - 无法构建它
我还看过一些博客,建议一个简单的基于令牌的方案(如this) - 这似乎是重新发明轮子但它确实具有概念上相当简单的优势 .
似乎在SO上有很多这样的问题,但没有好的答案 .
每个人在这个领域做什么?
6 回答
如果您希望以服务器到服务器的方式保护您的API(没有重定向到网站进行2腿认证) . 您可以查看OAuth2客户端凭据授予协议 .
https://dev.twitter.com/docs/auth/application-only-auth
我开发了一个库,可以帮助您轻松地为WebAPI添加此类支持 . 您可以将其安装为NuGet包:
https://nuget.org/packages/OAuth2ClientCredentialsGrant/1.0.0.0
该库面向.NET Framework 4.5 .
将包添加到项目后,它将在项目的根目录中创建自述文件 . 您可以查看该自述文件以了解如何配置/使用此程序包 .
干杯!
继续@ Cuong Le的回答,我的方法是防止重放攻击
//使用共享私钥(或用户密码)加密客户端的Unix时间
//将其作为请求标头的一部分发送到服务器(WEB API)
//使用共享私钥(或用户密码)解密服务器上的Unix时间(WEB API)
//检查客户端的Unix时间和服务器的Unix时间之间的时差,不应大于x秒
//如果用户ID /哈希密码正确且解密的UnixTime在服务器时间的x秒内,则它是有效请求
我建议首先从最简单的解决方案开始 - 也许简单的HTTP基本身份验证HTTPS就足够了 .
如果不是(例如,您不能使用https,或需要更复杂的密钥管理),您可能会看到其他人建议的基于HMAC的解决方案 . 这种API的一个很好的例子是Amazon 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/
Web API引入了一个Attribute
[Authorize]
来提供安全性 . 这可以全局设置(global.asx)或者每个控制器:
当然,您的身份验证类型可能会有所不同,您可能希望执行自己的身份验证,当发生这种情况时,您可能会发现从Authorizate Attribute继承并扩展它以满足您的要求:
在你的控制器中:
以下是WebApi授权的其他自定义实现的链接:
http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/
你试过DevDefined.OAuth吗?
我用它来保护我的WebApi与2-legged OAuth . 我也成功地用PHP客户端测试了它 .
使用此库添加对OAuth的支持非常容易 . 以下是如何实现ASP.NET MVC Web API的提供程序:
1)获取DevDefined.OAuth的源代码:https://github.com/bittercoder/DevDefined.OAuth - 最新版本允许
OAuthContextBuilder
可扩展性 .2)构建库并在Web API项目中引用它 .
3)创建自定义上下文构建器以支持从
HttpRequestMessage
构建上下文:4)使用本教程创建OAuth提供程序:http://code.google.com/p/devdefined-tools/wiki/OAuthProvider . 在最后一步(访问受保护资源示例)中,您可以在
AuthorizationFilterAttribute
属性中使用此代码:我已经实现了我自己的提供程序,所以我没有测试上面的代码(当然除了我在我的提供程序中使用的
WebApiOAuthContextBuilder
)但它应该工作正常 .Update:
对于对JWT感兴趣的人,我已经在这里提出了另一个答案,如何对Web API使用JWT身份验证:
JWT Authentication for Asp.Net Web Api
我们设法将HMAC身份验证应用于安全Web API,并且它运行正常 . HMAC身份验证为每个使用者使用一个密钥,消费者和服务器都知道hmac哈希消息,HMAC256应该是用过的 . 大多数情况下,消费者的散列密码被用作密钥 .
消息通常是根据HTTP请求中的数据构建的,甚至是添加到HTTP头的自定义数据,消息可能包括:
时间戳:发送请求的时间(UTC或GMT)
HTTP动词:GET,POST,PUT,DELETE .
发布数据和查询字符串,
网址
在引擎盖下,HMAC身份验证将是:
在构建签名(hmac哈希的输出)之后,消费者向Web服务器发送HTTP请求,HTTP请求的模板:
GET请求的示例:
要获取签名的哈希消息:
带有查询字符串的POST请求示例(下面的签名不正确,只是一个示例)
要哈希以获取签名的消息
请注意,表单数据和查询字符串应该是有序的,因此服务器上的代码获取查询字符串和表单数据以构建正确的消息 .
当HTTP请求到达服务器时,实现了一个身份验证操作过滤器来解析请求以获取信息:HTTP动词,时间戳,uri,表单数据和查询字符串,然后根据这些来构建签名(使用hmac哈希)和秘密密钥(散列密码)在服务器上 .
使用请求上的用户名从数据库获取密钥 .
然后,服务器代码将请求上的签名与构建的签名进行比较;如果相等,则传递身份验证,否则失败 .
构建签名的代码:
那么,如何防止重放攻击呢?
为时间戳添加约束,例如:
(servertime:请求到服务器的时间)
并且,将请求的签名缓存在内存中(使用MemoryCache,应该保持在时间限制内) . 如果下一个请求与前一个请求的签名相同,则会被拒绝 .
演示代码如下:https://github.com/cuongle/Hmac.WebApi