如何在RESTful WCF API中实现HMAC身份验证

12
我们正在使用WCF构建RESTful API(目前是.Net 3.5,但很快将移动到.Net 4)。我们已经有了一个功能框架,但目前没有安全保障。它需要从.Net应用程序以及iOS、Android和Web应用程序中访问。
我们想使用HMAC身份验证方案,如这里这里所述,但这两个示例似乎在描述如何验证哈希时出现问题。第一个示例未能描述UserKeys对象(哈希表?),而第二个示例缺少客户端和服务器端的GetUserKey方法。
有人能够解释这些示例中“用户密钥”/令牌是如何生成/存储/检索/使用的,或者提供一个更好的示例(如果可能的话,包括源代码)来使用HMAC授权在RESTful WCF服务中吗?
编辑: 经过更多的研究,我们确定需要更多的“授权”技术而不是“认证”技术(语义?)。我们实现了基本授权并在SSL后面保护了API。基本授权使用与HMAC 身份验证方案相同的Web请求中的“Authorization”标头,但传递编码为Base64的用户名:密码字符串,而不是令牌。这使我们能够根据我们的数据库自定义验证用户,以确定用户是否有权访问所需的API方法并具有适当的安全权限。 当然,我们非常乐意听取有关如何完成自定义用户名/密码验证和其他保护API方法的其他选项。

3
“rest”标签被移除了吗?对于使用WCF的RESTful API来说,这不是一个合适的问题吗? - Steven King
2个回答

17

获取用户密钥只是实现细节,你可以按任何你喜欢的方式进行操作,但通常在服务器上与用户名一起存储在数据库中。

基本方法很简单。

  1. 服务器和客户端以某种方式交换用户使用的共享密钥。这可以通过任何你喜欢的方式进行,包括发送传统的信件。很多时候这就是用户输入的密码。
  2. 当客户端想要发送请求时,他会构建完整的请求,然后使用密钥计算整个消息体(以及必要时的部分消息头)的哈希值。
  3. 接下来,客户端将计算出的哈希值和他的用户名添加到消息头中的一个位置,并将其发送到服务端。
  4. 服务端从消息头中检索出用户名,并在自己的数据库中搜索该用户的私有密钥。
  5. 然后,服务端使用密钥生成哈希值,计算消息体(和选定的消息头)的哈希值。
  6. 如果客户端发送的哈希值与服务器计算的哈希值匹配,则服务器知道该消息是由真正的客户端发送的,并且没有被修改过。

真正棘手的部分在于与用户共享保密密钥并保持其安全。因此,一些服务允许生成有限生命周期的共享密钥,以便将密钥提供给第三方,以便暂时代表你进行工作。


这有助于解释身份验证方法,从而引导我们对我们的需求进行更多研究。我们仍然不清楚如何使用HMAC /密钥方法比基本授权(用户名:密码)方法与SSL更好地授权特定用户访问API方法。 - Steven King
任何授权方案的第一步都是身份验证。毕竟,如果您不能确定另一方的身份,如何决定另一方是否被允许执行某些操作呢? - Maurice
我们添加了一个继承IHttpModule的类,检查Authorization头,并创建一个带有GenericIdentity的GenericPrincipal(类似于此处描述的内容)。它处理401 / WWW-Authenticate握手。它允许客户端发送用户名/密码,并允许我们根据我们的数据库验证用户。我们不必交换秘密密钥。由于它包装在SSL中,我们获得了安全连接和我们想要的自定义授权。这种方法适用于RESTful API吗? - Steven King
是的,这是一个在很多地方都被广泛使用的完全可行的选项。不过你仍然在交换一个秘密密钥,只不过在这种情况下它被称为密码 :-) - Maurice

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接