【问题标题】:How to validate user's access to specific rows in a SQL table?如何验证用户对 SQL 表中特定行的访问权限?
【发布时间】:2015-07-20 23:03:03
【问题描述】:

我正在处理一个项目,而且我对 Web 应用程序和 SQL 都是新手,所以请耐心等待。我正在构建一个 API,我想确保我的用户只能访问特定表中的某些行,这些行在另一个表中具有其客户 ID 的外键,但必须通过另一个表中的用户 ID 进行验证。 (一个客户有多个用户并拥有多个资产。目前,客户的所有用户都可以访问任何资产,但没有客户共享资产或用户。)我认为这样做的方法是这样做

SELECT * FROM [Asset] WHERE Id=@AssetId AND CustomerId=(SELECT CustomerId FROM [User] WHERE UserId=@UserId);

这很好,但是由于 Asset 和 User 表中有许多条目,此查询可能会占用大量时间。这很糟糕,因为对我的 API 发出的每个需要资产数据的请求都应该进行此检查。我可以设置一个索引,实际上 UserId 是 User 中的辅助键,因为它是来自身份验证提供程序的唯一标识符,但我不确定是否应该在 Asset.xml 中为 CustomerId 添加索引。与其他一些表相比,资产表的增长应该相对缓慢(有一个用于审计目的的消息记录表),但我不确定这是否是正确的答案,或者是否有一些更简单的更优化的答案。还是这种查询速度如此之快以至于我无需担心?

【问题讨论】:

  • 如果您的表足够大,您应该受益于 CustomerId 上的索引以加快两个表之间的连接,并从 UserId 上加快查找速度。另外,您是否考虑过在 Azure SQL 数据库上使用新的行级安全功能?它旨在通过自动为您应用访问逻辑来简化这些类型的查询。 msdn.microsoft.com/en-us/library/Dn765131.aspx

标签: sql tsql authentication azure-sql-database azure-api-apps


【解决方案1】:

对于您的特定情况,在 User 表和 Asset 表之间构建 junction 表似乎是完美的上下文。这两个字段一起将成为主键。 AssetId 和 UserId 分别为foreign keys.

假设联结表名为 AssetUser。

外键

CONSTRAINT [FK_AssetUser_User] FOREIGN KEY ([UserId]) REFERENCES [User]([UserId])

CONSTRAINT [FK_AssetUser_Asset] FOREIGN KEY ([AssetId]) REFERENCES [Asset]([AssetId])

主键

CONSTRAINT [PK_AssetUser] PRIMARY KEY([AssetId], [UserId]));

除非您将拥有大量数据和/或性能对您的应用程序至关重要,否则您不必担心规模太大。如果是这样,您可以选择使用 hadoop 或迁移到 NoSQL 数据库。

【讨论】:

  • 如何使用外键?我不能在资产中拥有用户的外键,因为多个用户可以访问相同的资产,但两者都有客户的外键。
  • 哦,好吧,我已经设置了UserId作为辅助键,所以在User中搜索很快。如果我设置了这个联结表,我可以假设允许客户单独向其组织中的各个用户授予对各个资产的访问权限。
  • 是的,您将获得更大的灵活性,而且速度会更快!
  • 所以我使用特定 UserId 访问特定资产的查询看起来像这样? SELECT * FROM [Asset] WHERE Id=(SELECT AssetId FROM [AssetUser] WHERE AssetId=@AssetId AND UserId=@UserId);
  • 要获取所有其他用户资产,您可以在上述评论中更改您的查询... WHERE Id IN (...)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 2014-02-18
相关资源
最近更新 更多