在我的典型应用中,用户单击aspx页面中的按钮,调用C#业务对象,然后运行存储过程。
是否应该在堆栈顶部,堆栈底部或每个级别进行角色检查?似乎恶意用户可以调用一个方法,他可以调用任何方法,所以为了有效的安全性,你需要检查每个方法(并且这需要编写很多额外的代码)。
这是一个典型的调用堆栈来说明我的问题:
Page_Load()
{
if(p.IsInRole("Managers")) //or equivalent attribute
{
AddAccount.Visible =true;
}
}
AddAccount_OnClick()
{
if(p.IsInRole("Managers")) //or equivalent attribute
{
//Add the account
Account.Add(...); //and maybe another role check...
}
}
-- TSQL doesn't understand .NET authorization, this call is in a 'trusted' subsystem
create proc Add_Account @user, @account_name
If @user in (Select user from role_table where role='manager')
-- Add the account
答案 0 :(得分:3)
从实现角度来看,尽可能在堆栈中实现检查是最好的解决方案,因为需要保护的函数数量最少,因此最容易陷入困境的事情和所有用户输入必须通过受保护的层。如果您的基金会受到保护,您无需关心在此基础上构建的所有内容。
此解决方案有一个明显的缺点 - 用户界面对身份验证,授权,数据验证以及所有其他内容一无所知。因此,每个输入都会进入堆栈,可能会导致错误,然后再次向上移动以通知用户。这将导致令人不愉快的用户体验,因为仅在将数据传递到后端系统之后才检测到在用户界面中可以容易地检测到的错误。因此,您还将向用户界面添加许多检查,以便提供更好的用户体验。
如果您使用基于界面的编程,这根本不是问题,因为您可以在应用程序层之间共享验证代码。这使您可以进一步轻松地将验证代码添加到所有应用程序层,这将为您提供深度防御 - 一个应用程序层中的错误可以被另一个层捕获。当然,如果验证代码本身是错误的并且您在应用程序层中共享它,则错误和错误可能会在所有应用程序层中进行探测。
答案 1 :(得分:3)
在我看来,你应该尽可能接近数据。您越接近数据,就越能确保无法通过代码库来绕过访问检查。
该参数将调用安全检查放在数据源本身,如果它支持它(如您最喜欢的RDBMS)或数据访问层。
然而,一些安全限制具有强烈的商业逻辑气味;例如“如果用户担任此角色并尝试修改符合这些规范的数据,则应允许该操作;否则不允许”。这听起来像是一个策略,并且属于单独的规则引擎的业务逻辑层。
I wrote about something similar in the context of WCF some time ago
答案 2 :(得分:2)
我会将角色访问检查放在实际执行潜在危险/敏感内容的业务对象中。
将角色检查添加到页面加载和按钮单击事件将是无关紧要的,恕我直言。此外,如果您要保护页面,请使用web.config中的声明性位置指令保护页面...将所有“管理”页面放在一个单独的文件夹中,并以声明方式保护整个文件夹。
但是,您应该始终对业务对象方法进行检查。
答案 3 :(得分:2)
您需要将其放在方法级别。您不能假设您以任何特定方式达到该方法。该方法可以由按钮处理程序调用,也可以作为任何类型逻辑的结果在普通代码中调用。你有多少次见过这样的东西叫做按钮处理程序......
private void MyBypassingCall()
{
if( myLogic )
{
AddAccount_OnClick();
}
}
所以把它放在Page_Load上是不够的。您还应该检查用PrincipalPermissionAttribute装饰方法。这减少了许多代码。
答案 4 :(得分:2)
这只是一个轶事评论,说明在业务方面进行安全验证的重要性。在我们的案例中,对请求黑客的低预期持乐观态度是不够的。我们的业务对象中没有任何验证,并以意想不到的方式被烧毁。客户构建了一个脚本来自动使用我们的站点。它最终跟随他们的脚本中未实际呈现的预期链接。它最终破坏了数据。当然,这对我们来说更像是系统状态和数据完整性问题,而不是安全漏洞,但我认为两者都适用。
答案 5 :(得分:1)
业务对象。
但是在施工时。让每个实例捕获一个非常具体的角色。
编辑:这种方式更简洁。