In my typical app, the user clicks a button in an aspx page, invokes a C# business object, then runs a stored procedure.
Should role checks be done at the top of the stack, the bottom of the stack or at every level? It seems that if a malicious user can invoke one method, he could invoke any, so for effective security, you'd need a check on every method (and that's a lot of extra code to write).
Here is a typical call stack to illustrate my question:
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
In my opinion, you should put it as close to the data as possible. The closer you are to the data, the better you can ensure that it isn't possible to take some circuitous route through your code base to circumvent an access check.
That argument would call for security checks being placed in either the data source itself, if it supports it (like your favorite RDBMS), or the data access layer.
However, some security constraints have a strong odour of business logic; e.g. "if the user is in this role and attempting to modify data that meet these specifications, the operation should be allowed; otherwise not". That sounds to me like a policy, and something that belongs either in the Business Logic layer of a separate Rules Engine of sorts.
I wrote about something similar in the context of WCF some time ago.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With