我希望提高通过 SSL 访问的现有 REST API 的安全性。Web 服务是多租户的,因此每个租户都有一个分配的 TenantId。
我面临的问题可以概括为:
- 如何确定租户?
- 如何确定客户端是否合法?
- 基于 HTTP cookie 的安全性是否适合该任务,还是我应该考虑基于令牌?
目前
目前,我们手动向每个客户端发出(即进程外 - 通过电话等)API 密钥,它们作为 HTTP 标头包含在每个请求中。此 API 密钥映射到 TenantId。当客户端向 REST API 发送登录请求时,我们会确定 TenantId,这反过来又允许我们检查正确租户数据库中的用户名/密码。一旦成功,我们就会发出一个有时间限制的 HTTP cookie。然后,该 cookie 将用于后续的 REST 请求。在内部,该 cookie 链接到会话,并且会话包含用户配置文件信息以减少数据库负载。
我们知道这有一些固有的安全风险。API 密钥可以很容易地从反汇编的客户端源代码中提取。我们还打算将我们自己的客户端构建为 JavaScript 中的 SPA,任何人都可以阅读。虽然我们可以撤销/更改密钥,但我正在寻找更安全的标准化实现。
选择
据我了解,我可以使用基于令牌的cookie 替代方案。HMAC 是 Web 应用程序的常见身份验证机制,但这需要在客户端和服务器中存储共享密钥。这个秘密似乎和上面的 API 密钥有同样的问题;因为它可以被泄露。
我还阅读了一些关于 JWT 的内容,它似乎扩展了 HMAC 概念,因为服务器可以将用户“会话”数据保存在令牌中,从而减少了对用户/配置文件信息的数据库调用次数。JWT 令牌用作用户名/密码登录成功的结果。因此这里没有共享秘密问题对吗?
我还阅读了一些关于 OAuth2 的内容,特别是Resource Owner Password Credentials Grant。我什至不确定 OAuth2 是否能解决我的问题。
确定租户
第一步是确定租户。除了使用 API 密钥映射到 TenantId 之外,我还可以:
- 在登录请求中请求 TenantId
- 使用子域映射映射到 TenantId
验证应用程序调用者
其次,我需要确定是否允许给定的客户端应用程序访问 REST API。在这方面,我完全没有好主意。这就是 OAuth2 来救援的地方吗?
我能想到解决这个问题的唯一方法是在用户登录后向调用应用程序发出一个临时过期的 API 密钥。虽然它不能保证应用程序不是恶意的,但它确实降低了攻击者的风险谁还获得了对用户凭据的访问权限。
我当前的 HTTP cookie 解决方案是否可以接受?我是否需要改用基于令牌的身份验证机制?
我欢迎您提出任何建议。我正在浏览大量信息,并试图弄清楚这一切。任何指导都会很高兴收到!