With Domain Driven Design in mind, how would you implement user Authorization in a repository? Specifically, how would you restrict what data you can see by the user provided login?
Lets say we have an e-commerce Mall that stores products, where only some products are maintained by any given store manager. In this case, not all products should be seen by any given login.
Questions:
- Would you select all products in the Repo, then use a filter to restrict what products are returned?
Like GetProducts("keyword: boat").restrictBy("myusername")? - Would you read the login from the controllercontext within the repository and filter results passively?
- How would you store the relation between a user role and what entities it could access? Would you simply store the entity key and the role in a many-to-many table, having one record for each product that each store manager could access?
Code examples or links to code examples would be fantastic. Thank you.
The tack that I’ve taken is to use attributes on the controller action that examines the relation between the current user and the entity being requested, then either allows or disallows the action based on the results of the look up. I have a couple of different attributes depending on whether it goes through a join table or has a direct relationship. It uses reflection against, in my case the data context, but in yours the repository(ies) to get and check that the values match. I’ll include the code below (which I’ve made some efforts to genericize so it may not compile). Note you could extend this to include some notion of permission as well (in the join table).
Code for the direct relationship attribute. It verifies that the current user is the owner of the record (the specified “id” attribute in the routing parameters matches the id of the current user in the user table).
This is the code for the association attribute, i.e., there exists an association in a join table between the id in the routing parameter and the user’s id from the user table. Note that there is a dependency on the System.Linq.Dynamic code from the VS2008 Samples.