2012-12-07 72 views
10

分开后,我有复合键与多租户数据库REST API的客户端

clientId - docId 

路由看起来是这样的

/api/controller/clientId/docId 

为了验证我使用了“全球多租户数据库“用户名,例如电子邮件+密码,通过https在每个请求的http-header中发送。用户名显式映射到客户端,并在后端可用。

什么是与休息,做正确,并有最佳的安全的方式吗?

  1. 路线等上方和正验证根据用户名的的clientId比在路由

  1. 更改,如下所述路由相同,并从的clientId保存记录之前的数据库?

    /api/controller/docId

这可能是一个很明显的问题,但我很担心潜在的安全问题。或者只是简单的路由选择而已?

谢谢!

回答

8

我觉得/api/controller/docId可能是最好的办法还是使用单一的代理键来代表客户端Id和的docId(我的偏好)。

除非您需要允许客户端查看其他客户端资源,否则我会将其从URI方案中隐藏起来,在最坏的情况下,它可能被认为是信息泄漏,因为您已验证客户端并知道他们是谁。这也是一个开销,即你仍然必须检查在URL中的客户端ID映射到请求的用户名和密码,所以你需要反正检索每个请求的客户端ID。

如果你看如何等多租户环境中工作,例如销售队伍的你可以看到他们必须通过安全机制来推断客户,或者有幸为每个对象/资源拥有一个唯一的ID。

我见过的一种方法是在URL的根把客户标识符(通常somekind的的代理键,避免让其他用户数据库的ID!)如/ API/{的clientId} /控制器/的docId。在多租户环境中,每个资源可能/根据定义,该客户端是唯一的。

有时这种方法给的理由是,有每个客户助攻唯一的URL与缓存.../API/{}的clientId /控制器/的docId或/ API /控制器/ {}的clientId /的docId

关于基本身份验证的简要说明

您的方法没有任何问题,但请考虑......您可以在验证密码和用户名时检索客户端ID,并将其添加为原则上的声明。至少可以在代码中使用,而无需进一步查找数据库(在请求的生命周期内)。

更进一步...考虑一个两步认证机制,其中令牌作为声明在令牌中发放(遵循正确的用户名和密码),而客户端ID实际上在令牌中。这样,使用令牌的后续请求意味着您将不需要为每个请求回拨数据库来验证和检索信息。看看OAuth承载令牌http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html(一定要签名)或其他一些方法...

5

马克的方法是完全有效的,但是,我碰巧使用/tenant/docid,因为每个租户都有不同的数据库。如果您不在URI中包含租户,那么试图确定要连接哪个数据库并搜索该文档将会是一个真正的痛苦。

+0

我也有类似的情况。您是否考虑将租户ID存储为用户声明(或访问令牌/凭证上的类似内容)?我认为将租户作为URI的一部分是理想的,但在应用于现有软件时需要更多的工作。 – bjornhol

+2

@bjornhol如果租户ID不包含在URL中,那么它会使本地缓存变得困难,因为我使用整数而不是标识符的guid,因此租户之间可能会发生冲突。 –