This project is read-only.
In the majority of applications dealing with complex business domains, authorization rules are often dependent on complicated conditions being hard to translate into an application code. Before delving into Themis proposal of solving these cases, you can find a short evolution of an authorization code, from the simplest cases to the most complex.

Role only

var canBorrowABook = _roleProvider.IsInRole("LibraryUser");
This code can be considered as the simplest version of authorization one can make. Of course question about being authenticated can be considered as authorization as well but it does not introduce nothing interesting to the discussion.
Having this kind of authorization each permission check should be written explicitly, without a global control of authorization conditions. It's obvious that this code finally will turn into a nightmare making a developer to run throughout a project again and again, changing business rules in many places.

Named permission

var canBorrowABook = _authorizationService.Check("canBorrowABook");

// other code in authorization service implementation
if (permission== "canBorrowABook")
	return _roleProvider.IsInRole("LibraryUser")
The permission can be identified by name and resolved by an implementation of an authorization service. The implementation simply translates a name of a permission into call to a role provider, checking again the same thing: whether a logged in user is in a role. This shift allows reusing the name of permission across all the code in an application providing one place to change one rule.

Partially contextful permission

What about a case when one user, having LibraryUser can borrow only books which has CanBeBorrowed flag set to true? The previous example does not cover it since no context was passed to the authorization service. We can presume, that an example code, satisfying the need of checking one property value, can look like:
var book = _session.Get<Book> (5);
var canIDoSth = _authorizationService.Check("canBorrowABook", book);

// other code in authorization service implementation
public class AuthorizationService
{
	public bool Check (string permission, object param)
	{
		if (permission == "canBorrowABook" && param is Book && ((Book)param).CanBeBorrowed)
			return _roleProvider.IsInRole("LibraryUser")
	}
}
It's getting nasty, isn't it?

Fully contextful

The previous case was partially contextful. It checked only one property of an entity. What about a requirement: "only users which are LibraryUser and were registered before year 2000 can borrow a book having CanBeBorrowed set to false. This requirement is considered as fully contextful because of dependence on an entity (book) and another value which can be described as role context. Having it done in a manner of previous examples would create a monster method of authorization service, not to mention cost of incorporating getting a user registration date.

Filtering SQL

Imagine the very last situation. Business says that a user with LibraryUser can see on a list only books which he/she is capable of borrowing. Having authorization service implemented this way it would be a horror to make it work quickly.

This can be done in a much more elegant way. Visit the next section: IDemand<T> and IClaim

Last edited Feb 26, 2011 at 9:49 AM by scooletz, version 15

Comments

No comments yet.