摘要:我需要根据网址查询字符串中的数据来授权网页,而不仅仅是网页名称。
背景:
假设我正在建立图书馆库存系统。可以在管理员或用户角色中创建用户并将其分配给单个库。同一数据库中有数百个竞争库,因此确保一个库的用户无法查看其他库中的库存非常重要。
现在我正在使用一个非常标准的ASP.NET设置:使用SqlMembershipProvider进行表单身份验证。使用SqlRoleProvider进行授权,通过web.config中的<authorization>
部分进行配置。使用SiteMap提供程序进行安全修整以隐藏未经授权的页面。
要控制库存信息泄漏,我会手动检查用户的关联库ID与每个库存查询。它有效,但它很乏味且容易出错。必须有更好的方法。
问题:
现在,用户可以在库中创建任意“集合”。 (例如,集合A中包含图书1,2和3)。管理员希望能够授予管理员/用户访问权限,而不仅仅是整个库。
因此,如果用户转到www.com/Book.aspx?BookId=1
,系统需要确保用户在显示页面之前拥有“Book 1”所在的集合的权限。如果他们访问www.com/Reviews.aspx?ReviewId=23,我需要确保“评论”适用于他们有权查看的集合中的图书。
1)如何以最标准的ASP.NET方式实现这一点?
在基页内手动检查?
一个自定义的HttpModule?
自定义角色提供程序?
我对如何存储管理员/用户权限不感兴趣,而是根据这些权限授权的方式/位置。
(赞赏如何实施其中任何一项的示例)
2)为了进一步复杂化,我仍然希望安全修整来检查用户是否拥有任何集合或库的管理员权限,如果他没有,则隐藏管理页面。
答案 0 :(得分:2)
我不会在UI(ASP.NET)层附近处理它,而是在应用程序服务中处理它。类似的东西:
IPrincipal
(或您的自定义用户对象)
作为构造函数参数。从长远来看,这将是更多可测试和可用的,然后从ASP.NET UI方面担心它。
如果您必须在ASP.NET端处理它,我会考虑使用自定义IPrincipal
和自定义RoleProvider
将每个库包装为要访问的角色,然后您可以使用大多数LoginView
等控件。
答案 1 :(得分:1)
通常,这种事情是在数据级别处理的。它与ASP.NET几乎没有关系,除了最终你需要一个用户ID(来自Membership)。你所做的是找到你想控制访问权限的实体的一部分,然后你创建所有的查询来过滤它。
例如,如果您在库级别进行访问,那么您将在用户和库之间添加关联。这可以是1:1,1:许多,很多:很多,无论您的数据模型需要什么。关键是通过此级别加入将始终不返回任何记录,因此您的整个查询将不返回任何记录。
示例,假设用户只能属于一个库。
用户表具有LibraryID,Books表具有LibraryID,这使得用户和书籍之间实现了有效的多对多连接。因此,您在LibraryID上加入User和Library,并在LibraryID上加入Library和Books,然后查询将返回属于与该用户相关联的库的书籍。
通过这种方式,用户无法查询与其无直接关联的任何内容。安全性完全在数据库中,不需要业务逻辑。