如何在 RESTful WCF API 中实现 HMAC 身份验证
Posted
技术标签:
【中文标题】如何在 RESTful WCF API 中实现 HMAC 身份验证【英文标题】:How to implement HMAC Authentication in a RESTful WCF API 【发布时间】:2012-01-11 21:28:34 【问题描述】:我们正在使用 WCF(当前为 .Net 3.5,但很快将迁移到 .Net 4)构建一个 RESTful API。我们有一个功能框架,但它目前是不安全的。它需要可从 .Net 应用程序以及 ios、android 和 Web 应用程序访问。
我们希望使用 here 和 here 中描述的 HMAC 身份验证方案,但在描述如何验证哈希时,这两个示例似乎都分崩离析。第一个示例无法描述 UserKeys 对象(哈希表?),第二个示例缺少客户端和服务器端的 GetUserKey 方法。
任何人都可以解释如何在这些示例中生成/存储/检索/使用“用户密钥”/令牌,或者提供一个更好的示例(如果可能,请提供源代码)如何在 RESTful 中使用 HMAC 授权WCF 服务?
编辑: 经过更多研究,我们确定我们需要更多的“Authorization”技术而不是“Authentication”技术(语义?)。我们实施了基本授权并保护了 SSL 背后的 API。 Basic Authorization 使用与 HMAC Authentication 方案相同的 Web 请求中的“Authorization”标头,但传递的是使用 Base64 编码的 username:password 字符串而不是令牌。这使我们能够针对我们的数据库对用户进行自定义验证,以确定该用户是否已获得许可并具有访问所需 API 方法的适当安全权限。
我们当然愿意听取有关如何完成自定义用户名/密码验证和其他保护 API 的方法的其他选项。
【问题讨论】:
“rest”标签被删除了?对于使用 WCF 的 RESTful API,这不是一个合适的问题吗? 【参考方案1】:检索用户密钥只是一个实现细节,您可以按照自己喜欢的方式进行操作,但在服务器上,它通常与用户名一起存储在数据库中。
基本方法非常简单。
-
服务器和客户端以某种方式交换了一个共享密钥供用户使用。这可以通过您喜欢的任何方式完成,包括发送老式的死树式信函。通常这只是用户输入的密码。
当客户端想要发送一个请求时,他会构建完整的请求,然后使用密钥计算整个消息体(如果需要,还可以选择一些消息头)的哈希值
接下来,客户端将计算得到的哈希值和他的用户名添加到消息中的一个标头中,并将其发送到服务。
该服务从消息头中检索用户名,并在其自己的数据库中搜索该用户的私有 keu。
接下来,他使用密钥计算消息正文(和选定的标头)的哈希值以生成其哈希值。
如果客户端发送的哈希值与服务器计算的哈希值匹配,服务器就知道消息是由真实客户端发送的并且没有以任何方式更改。
真正唯一棘手的部分是与用户共享密钥并确保其安全。这就是为什么某些服务允许生成具有有限生命周期的共享密钥,以便您可以将密钥提供给第三方以临时代表您工作。
【讨论】:
这有助于解释 Authentication 方法,从而对我们的需求进行了更多研究。我们仍然不清楚如何使用 HMAC/key 方法来授权特定用户对 API 方法的访问,而不是使用 SSL 的基本授权(用户名:密码)方法。跨度> 任何授权方案的第一步都是身份验证。毕竟你怎么能决定是否允许另一方做某事是你不能确定对方的身份。 我们添加了一个继承 IHttpModule 的类,检查 Authorization 标头,并创建一个具有 GenericIdentity 的 GenericPrincipal(类似于 here 的描述)。它处理 401/WWW-Authenticate 握手。它允许客户端发送用户名/密码,并允许我们根据我们的数据库验证用户。我们不必交换密钥。由于它包含在 SSL 中,因此我们获得了我们想要的安全连接和自定义授权。这种方法是否适合 RESTful API? 是的,它是在很多地方使用的完美选择。不过,您仍在交换密钥,在这种情况下称为密码 :-) 知道了。感谢您对此的帮助。【参考方案2】:我们可以在此处找到 HMAC 的实现
https://github.com/cuongle/WebAPI.Hmac
【讨论】:
以上是关于如何在 RESTful WCF API 中实现 HMAC 身份验证的主要内容,如果未能解决你的问题,请参考以下文章