We are using ASP.NET with a lot of AJAX "Page Method" calls. The WebServices defined in the Page invokes methods from our BusinessLayer. To prevent hackers to call the Page Methods, we want to implement some security in the BusinessLayer.
We are struggling with two different issues.
First one:
public List<Employees> GetAllEmployees()
{
// do stuff
}
This Method should be called by Authorized Users with the Role "HR".
Second one:
public Order GetMyOrder(int orderId)
{
// do sutff
}
This Method should only be called by the owner of the Order.
I know it's easy to implement the security for each method like:
public List<Employees> GetAllEmployees()
{
// check if the user is in Role HR
}
or
public Order GetMyOrder(int orderId)
{
// check if the order.Owner = user
}
What I'm looking for is some pattern/best practice to implement this kind of security in a generic way (without coding the the if then else every time) I hope you get what i mean :-)
Secure design patterns are meant to eliminate the accidental insertion of vulnerabilities into code and to mitigate the consequences of these vulnerabilities.
OSA IT security architecture patterns are based on architectural overview diagrams depicting a certain information usage context. These diagrams are then annotated with references to the NIST controls catalog. Some patterns that get used repeatedly across many IT Security Architectures are called modules.
These layers will be called the temporal layer, the distribution layer and the data layer. The temporal layer will address time-based security and will feature workflow related solutions.
The presentation layer : It contains all categories related to the presentation layer. The business layer : It contains business logic. The persistence layer : It's used for handling functions like object-relational mapping. The database layer : This is where all the data is stored.
User @mdma describes a bit about Aspect Oriented Programming. For this you will need to use an external library (such as the great PostSharp), because .NET doesn’t have much AOP functionality. However, .NET already has a AOP mechanism for role based security, that can solve part of your problem. Look at the following example of standard .NET code:
[PrincipalPermission(SecurityAction.Demand, Role="HR")]
public List<Employees> GetAllEmployees()
{
// do stuff
}
The PrincipalPermissionAttribute is part of the System.Security.Permissions namespace and is part of .NET (since .NET 1.0). I’ve been using it for years already to implement role based security in my web applications. Nice thing about this attribute is that the .NET JIT compiler does all the weaving for you on the background and you can even define it on a class level. In that case all members of that type will inherit that attribute and its security settings.
Of course it has its limitations. Your second code sample can't be implemented using the .NET role based security attribute. I think you can’t really come around some custom security checks in this method, or calling some internal security library.
public Order GetMyOrder(int orderId)
{
Order o = GetOrderInternal(orderId);
BusinessSecurity.ValidateOrderForCurrentUser(o);
}
Of course you can use an AOP framework, but you would still have to write an framework specific attribute that will again call your own security layer. This would only get useful when such an attribute would replace multiple method calls, for instance when having to put code inside try,catch,finally statements. When you would be doing a simple method call, there wouldn’t be much difference between a single method call or a single attribute IMO.
When you are returning a collection of objects and want to filter out all objects for which the current user doesn't have the proper rights, LINQ expression trees can come in handy:
public Order[] GetAllOrders()
{
IQueryable orders = GetAllOrdersInternal();
orders = BusinessSecurity.ApplySecurityOnOrders(orders);
return orders.ToArray();
}
static class BusinessSecurity
{
public static IQueryable<Order> ApplySecurityOnOrders(
IQueryable<Order> orders)
{
var user = Membership.GetCurrentUser();
if (user.IsInRole("Administrator"))
{
return orders;
}
return
from order in orders
where order.Customer.User.Name == user.Name
select order;
}
}
When your O/RM supports LINQ through expression trees (such as NHibernate, LINQ to SQL and Entity Framework) you can write such a security method once and apply it everywhere. Of course the nice thing about this is, that the query to your database will always be optimal. In other words, no more records will be retrieved than needed.
UPDATE (years later):
I used this attribute for a long time in my code base, but several years back, I came to the conclusion that attribute based AOP has terrible downsides. For instance, it hinders testability. Since security code is weaved with normal code, you can't run normal unit tests without having to impersonate a valid user. This is brittle and should not be a concern of the unit test (the unit test itself violates the Single Responsibility Principle). Besides that, it forces you to litter your code base with that attribute.
So instead of using the PrincipalPermissionAttribute
, I rather apply cross-cutting concerns like security by wrapping code with decorators. This makes my application much more flexible and much easier to test. I've written several articles about this technique the last couple of years (for instance this one and this one).
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