我目前正在创建一个网站,用户可以查看和修改他们的小部件。与存储在我的服务器上的小部件数据的所有交互都将通过 RESTful Web 服务完成。例如,如果用户想要查看他们的小部件列表,则执行流程将类似于:
https://www.example.com/Login.htm
并与服务器进行身份验证(在我的情况下是通过 OpenID 提供程序)https://www.example.com/Widgets.htm
getWidgets()
将被调用。 getWidgets()
将调用我的网络服务 https://www.example.com/Services/Widget/12345
renderWidgets(widgets)
的用户小部件列表进行响应。将更新 html 页面 我不希望除了用户 12345 之外的任何其他人访问他们自己的小部件,所以我猜
getWidgets()
将不得不为我的 Web 服务提供一些身份验证。我不确定实现这一目标的最佳方法是什么。我在想客户端和服务器可以有一个共享的 secret
getWidgets()
将发送到网络服务。服务器可以将此 key 生成为随机字符串(数字、GUID 或其他任何内容),并在客户端请求初始 HTML 页面时将其包含在响应 header 中。客户端将在向服务器发送请求时使用此 key 。这听起来像一个明智的想法吗?
这是一个常见的要求,所以有没有一种标准的方法来实现同样的事情?据我所知,这超出了 OpenID 的范围,OAuth 不适合。
提前致谢。
最佳答案
这是一个很好的问题 - 但我认为您的解决方案可能需要比您想象的更复杂一些。
通常,您想要验证这种场景的方式是 2 阶段握手。第一步是让您的应用程序向服务器提供一个私钥(由服务器生成,对于客户端应用程序是唯一的)以验证它实际上是一个有效的客户端。这为您的服务器提供了权威证据,证明请求来自它知道并且可以信任的软件。
然后,第二步是当用户登录您的客户端应用程序时,他们提供用户名/密码组合。此信息以及您的应用程序 key 都应通过 SSL 发送到服务器。
SSL 对数据进行加密,以便具有数据包嗅探器的第三方无法读取传输中的数据,服务器执行以下操作:
401: Unauthorized
响应或其他类似错误。 此时,客户端可以使用返回的 session ID,而无需继续重新提交应用程序 key 。
您的申请
现在,在您的情况下,您实际上可能在同一应用程序和同一服务器上托管客户端/服务器。在这种情况下 - 您通常可以跳过围绕私有(private)应用程序 key 的所有部分 - 而只是禁止跨站点脚本请求。
为什么? - 因为您真正要防范的是以下内容:
服务器 A 托管您的 RESTful API。
客户端 B、C 和 D 的主机客户端将依赖于服务器 A 的 API。您不希望客户端 E(不是您的应用程序 - 并且是恶意的)能够通过绕过或窃取其他客户端之一的凭据来访问服务器 A。
但是,如果客户端和服务器都托管在同一位置,因此具有相同的 URL - 即 RESTful API 位于
www.yourdomain.com/api
并且客户端位于 www.yourdomain.com/
- 您通常可以不允许任何源自 yourdomain.com
之外的 AJAX 类型的请求- 这是你的安全层。在这种情况下,您只需执行以下操作即可获得合理的安全级别:
/auth/login
的请求(或任何您的登录 POST
方法)通过 SSL 来(在 C# 中,这可以通过使用方法或 Controller 上的 [RequireHttps]
属性来完成)。 你的cookie应该包含什么?
理想情况下,cookie 应包含只有您的服务器才能解密的 2 路加密数据。换句话说 - 您可能会输入类似用户的
username
的内容。或 user_id
在 cookie 内部 - 但使用 Rijndael 或其他密码系统对其进行 2 路加密 - 使用只有您的服务器才能访问的加密密码(我建议使用随机字符串)。然后 - 当您收到附带 cookie 的后续请求时,您只需执行以下操作:
401: Unauthorized
响应(这是更改或伪造的 cookie)我希望这会有所帮助。 :) 如果没有 - 请随时发表任何评论并提出问题,我会尽力澄清。
关于javascript - RESTful Web 服务中的身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13186455/