This is a re-write of my previous question, as the original is lacking
in details.
I have a multi-tenant SaaS application, will be using a single
database, no client-specific custom logic or data. I'm looking at
more elegant methods of ensuring that the customer that is logged in
cannot "accidentally" view other customer's data. This is a hosted
application, single database option--part of the requirements, I can't
change that, nor does it make sense in my case. The dataset is too
small to warrant a Db per customer.
So, a customer's user logs into the system. Their customer and user
role are retrieved and stored in a session specific cookie. In every
controller method that retrieves data, the id of the data they are
requesting is verified against their session cookie Id. Thus, if a
user is requesting to view Product 124, then the Product.CustomerId is
compared to their session cookie of CustomerId to make sure that the
user has the correct privileges to view that product. Their role is
then used to determine what actions they may perform against that
Product, such as edit, delete, add, etc.
Right now, I have a function added to every controller method that
does this quick verification. It is duplicated code and I cringe
looking at it. I have not found a better way, although I'm positive
there is one.
I've looked at NHibernate's Filters (filter-def) which might work, but
I have not seen a good example implementation that would work in my
case. Also, Fluent NHibernate does not currently support Filters,
although someone has submitted a patch that would hopefully add that
functionality.
Not every entity has a CustomerId specific property, so I see no other
option than to manually add this extra parameter to my queries. My
main concern is preventing customers from accidentally seeing other
customers' data.
An alternative to using a cookie would be to just add it in the url
route. So, for Customer 777 requesting Product 123, it would look
like
http://example.com/Products/Details/777/123
That merely makes it more visible, yet it doesn't enforce that the
user from Customer 555 couldn't see it. The extra verification code
must exist somewhere.
It would be nice if there was a way to inject a method at the start of
every controller action, possibly tagged by an attribute (b/c
remember, not all actions require Customer specific validation
check).
I'm sure I'm overlooking something painfully obvious to others on this
group. Any thoughts?
Many thanks in advance,
todd