views:

58

answers:

3

I'm implementing system which uses role based access to different methods in classes. For example to perform any action I need to check whether user which uses it can do it.

I can write in each method:

if(User.IsInRole ...) {
} else {
return ... throw ... whatever
}

I was thinking about automating this process for example by adding attributes to this methods or maybe any other solution?

What would You suggest ?

A: 

Take a look at 'Aspect Oriented Programming' (AOP) libraries -- and the answers to this StackOverflow question. You can use AOP to add the role check code automatically.

Dr Herbie
+2  A: 

As long as you use principals things are already there...

[PrincipalPermission(SecurityAction.Demand, Role = "A role available on your principal")]
public void Foo()
{
  // Will throw an exception if the principal does not have the required role
  // Otherwise the method will execute normally
}
vc 74
+1  A: 

Do the check once at construction time, and throw (or return NULL from the factory) if the security condition is not met. Thereafter, holding a reference to a given model object is enough proof that you passed the security check at some earlier point. If you are worried that this could cause TOCTTOU issues, ensure that these objects become unusable at the end of an application-defined concept of "game turn" (typically the database transaction); this is a good practice anyway.

This approach of security is called capability discipline. Think of your objects as boxes that have some authority inside them (in their private variables). By pressing the buttons on the box, you can only exercise a tailored down fraction of this authority in the ways that the programmer of the object allows you to.

For example, say you are writing a calendar application with an SQL backend. There is the SQLTransaction object, which doesn't outlive the transaction (as per above) but still it has all the rights to all the tables that the application uses. That's a lot of power that you don't want to be passing around to users of your API (explicitly or by mistake, think SQL injection). Instead you hand out User objects that model the authority to write only to that user's row in the Users table; also a User can create, read, update, delete Appointment objects, which similarly represent limited authority in the Appointments table.

To maintain RBAC throughout your API, you must ensure that the following hold:

  1. Only legitimate users can get access to the User object that represents them. This is where you wire up the authentication system into the User constructor;
  2. The User objects do not leak authority, ie you have to audit your API to make sure that by exercising method calls on a User (or any related object they return, recursively) you cannot read or alter any resources that do not belong to this user. This is where you can apply the facet pattern — eg User.GetAppointments() returns real Appointment instances for appointments created by this user, but read-only wrappers for those created by someone else.
DomQ