Appropriate spot for security evaluations - business logic or data access - security

Pardon the length here...hopefully I didn't go overboard...
I'm in the process of working on my first production MVC application and I'm trying to stick to DDD principles in the process. I've run into some questions related to how to deal with the security requirements of the application and thought I'd see if the SO community could offer some best-practice suggestions.
Domain Information
To use a simplified explanation, this application will have AffiliateCompanies, Users, and Customers.
AffiliateCompanies are hierarchal, so one affiliate can sign up and be tied to the activities of another affiliate. The root is the main company providing the products/services.
Users all belong to an Affiliate entity.
Customers are organizations to which the products/services are sold. Affiliates are assigned to customers such that it is possible for two hierarchically-unrelated affiliates to split a Customer.
Security Information
Rights to perform certain actions in the application will be determined based on an ACL-type of arrangement. Each User object has a property that is a collection of SystemAccessRules that determine what actions they can perform and what the scope of their permissions are (their own objects, their affiliate's objects, or their entire hierarchy's objects). Users can also belong to roles, which themselves have that same collection of SystemAccessRules.
As a result, if a user logs in and wants to see a list of "their" customers, the list could be comprised of customers they are individually assigned to, customers anyone in their affiliate organization is assigned to, or customers anyone in their organization or any of their child affiliate organizations are assigned to.
Database Considerations
DDD aside, at some point the storage strategy has to come into play. In this simple scenario, the tables align with the objects above (including a roles table), with a few support tables to support the relationships between the objects:
AffiliateCustomers - this table allows for a many-to-many relationship between affiliates and customers by storing the PK of each entity as a pair of FKs that are themselves a composite PK for this table.
ACL - this table stores the security information, specifically the subject of the entry (either a user or a role), the action in question (e.g. "CreateCustomer"), the permission (allow or deny), and a scope (their own stuff, their organization's, or their network's).
The Question...Finally
I'm using a combination of repositories and services. I'm trying to keep business logic in the services and out of the repositories or database, but due to the security design here, a simple request for the list of "their" customers could be immensely burdensome, especially as the data set grows. I was trying to use Linq where possible, but this architecture seems not to be very suited. As I see it, here are my choices:
Accept the requesting user as an argument for service methods (or determine it by context), and have the service method populate a list through multiple queries to Linq repository. This would require pulling the list of customers, then iterating through each customer to issue another query to pull the ACL data, then using that data to filter the first list based on permissions. The hierarchy issue would require some fancy Linq footwork (like this), if it's possible at all.
Even if the hierarchy issue could be made to work, it seems like this solution won't perform very well...
Accept the requesting user as an argument, but pass it and the required permission (e.g. "View Customers") to the repository in order to retrieve appropriate data from the database through a stored procedure that would use several EXISTS clauses in a CTE query that could account for the hierarchical nature of the data and the need to check for role and user security.
This pushes a fair amount of logic to the database, which seems very anti-DDD and generally bad.
I'm leaning more toward the second option, but that may be because in my past projects that's how I've done it. I'm not even sure if my design overall is on the right track (in the past the permission declarations were done using bit flags, so it was even easier to do the DB query using bitwise operator).
Has anyone been in similar situations, and if so can you comment on the performance and maintainability of the solution you pursued? I want to stick to high-minded programming principles, but not at the expense of simplicity and common sense.

Have you considered using the specification pattern to pass your business rules down to your data access layer?
The service constructs a specification tree which it passes to the repository. The repository converts the specification into an Expression<Func<Customer, bool>> which it passes to IQueryable<Customer>.Where(...). When the repository materialises the collection, e.g. by calling ToList(), the business rules are translated into SQL and executed on the database server.
Last time I checked, LINQ to SQL didn't support CTEs, so you may need to use a view to flatten the hierarchy.

Related

Role creation based on MarkLogic permissions

MarkLogic 9.0.8.2
We have developed API to get & set data in MarkLogic, All data are stored in xml format within MarkLogic
Now we want to expose this API endpoint to external users with below operations
READ
INSERT
UPDATE
NODE-UPDATE
EXECUTE
ADMIN
So we want to create different user credentials based on permission like ReadOnly, ExecuteOnly.
What all Roles & Permissions we need to select to make sure they can perform what they are allowed to?
Note upfront: permissions are about document access, privileges about function access. Execute permission in specific only applies to module access, not document access.
There are many ways to organize your security, but ground basics are usually fairly similar. I'll provide a pattern for you, that I personally consider a good practice, and may prove to be a good general starting point for further expansion.
Start with 4 roles with no properties themselves. Put 'read', 'insert', 'update', and 'node-update' in the names.
Create a fifth role with 'defaults' in the name and give it default permissions for the above four roles, where the capability matches the role name (so 'read' for the read-role, etc).
Then create higher level roles for abstract notions like reader, writer, and maintainer. Reader only inherits the read role, writer inherits reader, insert, update and defaults. Maintainer inherits writer. Deletion is a special kind of update, and not distinguishable. Node-update is a subset of update. I have not come across a use case where I wanted to allow node-update, but not a full update.
Execute permissions makes no sense here, since that only applies to modules, not to documents. Execute privileges are used to allow using particular functionality (like sem:sparql, xdmp:http-get, etc). Apply them as appropriate to reader and writer roles.
Avoid applying more dangerous execute privileges like xdmp:spawn, and xdmp:eval to any of the above roles. If you come across a need for that, then create a role that you use for Amps (you can put 'amps' in the name somewhere), and make sure you use that role only for Amps, and never assign it to roles or users.
Last but not least, you often have multiple distinct datasets in the same database, and you might want to control document access to them independently. Consider looking into Compartment Security instead of creating a distinct set of roles per dataset in such cases.
HTH!

DDD Bounded Contexts Different Models For The Same Concept

I have an ERP project with multiple sub-domains. It is not using CQRS or domain events.
I have two sub-domains; CRM and Accounting. The customer concept needs to be modeled differently in the two sub-domains. CRM needs to know the size (number of employees) of the company but not the tax number. Accounting needs to know the tax number but not the size. The company name is needed by both sub-domains.
I am thinking of modeling both CRM Customer and Accounting Customer as entities. But then whenever a new customer is created by a CRM user, an Accounting Customer instance also needs to be created. And if a report needs information from both sub-domains, then the queries become more complicated then when you have single entity containing all the information.
Is this the way to go? Is there a better way? Does it make sense to have multiple sub-domains without utilizing domain events?
Are you sure you need DDD? The use case seems quite simple, maybe you just left out all the other complexities, but from just the info you're asking, a simple CRUD app would do. Data Centric apps, like reporting, don't need DDD. You need DDD when you must modify the data in strict ways, to maintain consistency.
If you are sure you do need DDD, then you need to understand the point of the model is to protect against the invariants of the domain. You say a CRM Customer must always have an equivalent Accounting Customer. How is this handled by the business today? How does accounting know about CRM customers? How does accounting know they're talking about the same customer as CRM? However they are doing it currently, is what you should try to model.
As an example, if they do it in real life by just letting the other one know. You could have your CRM context publish a new Customer event, and your Accounting context could react to it by creating an Accounting Customer for it.
If on the other hand, they both learn about it from something else, then maybe they both react to that other something's event.
If you don't want to use events, it could be a direct call, from the CRM context to the Accounting context. Though know that this would grow more restricted as the app grows, but if again you've got a simple domain, its no problem.
Also, querying data is not the same as modifying it. Queries should not use the domain model entities and value objects. It could, but it should not be constrained by it. That's because query is a read only operation. You need to put your data inside your domain model only when you are going to change it.

Is CouchDB per-user database approach feasible for users with lots of shared data?

I want to implement a webapp - a feed that integrates data from various sources and displays them to users. A user should only be able to see the feed items that he has permissions to read (e.g. because they belong to a project that he is a member of). However, a feed item might (and will) be visible by many users.
I'd really like to use CouchDB (mainly because of the cool _changes feed and map/reduce views). I was thinking about implementing the app as a pure couchapp, but I'm having trouble with the permissions model. AFAIK, there are no per-document permissions in CouchDB and this is commonly implemented using per-user databases and replication.
But when there is a lot of overlap between what various users see, that would introduce a LOT of overhead...stuff would be replicated all over the place and duplicated in many databases. I like the elegance of this approach, but the massive overhead just feels like a dealbreaker... (Let's say I have 50 users and they all see the same data...).
Any ideas how on that, please? Alternative solution?
You can enforce read permissions as described in CouchDB Authorization on a Per-Database Basis.
For write permissions you can use validation functions as described on CouchDB
The Definitive Guide - Security.
You can create a database for each project and enforce the permissions there, then all the data is shared efficiently between the users. If a user shares a feed himself and needs permissions on that as well you can make the user into a "project" so the same logic applies everywhere.
Using this design you can authorize a user or a group of users (roles) for each project.
Other than (as victorsavu3 has suggested already) handling your read auth in a proxy between your app and couch, there are only two other alternatives that I can think of.
First is to just not care, disk is cheap and having multiple copies of the data may seem like a lot of unnecessary duplication, but it massively simplifies your architecture and you get some automatic benefits like easy scaling up to handle load (by just moving some of your users' DBs off to other servers).
Second is to have the shared data split into a different DB. This will occasionally limit things you can do in views (eg. no "Linked Documents") but this is not a big deal in many situations.

Salesforce Objects and Normalization

I am a student developer with Oregon State University's Business Solutions Group and I am currently working on a Salesforce integration project for one of the University's colleges. As you can imagine, the data we are working with is coming from several different places and in a variety of different formats. I was wondering if anyone with more experience in setting up Salesforce object schemas could talk about the pros and cons of relational database style normalization in Salesforce. What do we gain by not normalizing and using Record Types to categorize data? (For example: a Person-Account that encompasses Students and Faculty and uses Salesforce Record Types to differentiate between the two) What do we lose?
This message was inspired by this webpage:
Salesforce Guru: Record Types
Notice that the first thing it advises is to not normalize (overmuch) because it prevents us from taking advantage of some built-in Salesforce functionality. Overall, the page seemed helpful, albeit incomplete.
The answer to this question seems critical to the success of our project and will help us to decide how to reorganize the data we are initially migrating to Salesforce and ultimately build our Salesforce object schema, so any thoughts, additional resources or advice are very much appreciated. Thanks!
The inspirational web page is correct. With the "standard objects" like Account, Contact, Case, Lead, etc. and even with custom objects the system works best to use fewer tables (objects) and segregate the data based on some value (such as record type).
By using record types you leverage the point-and-click UI. For example, for the Account object you have a default page layout. But for each record type you can have a unique page layout. Furthermore the security model uses record types to limit or grant access as appropriate to different user profiles.
As the author says SOQL is NOT SQL.

When should I use ACL in my application

I am pretty much confused as to when I should implement an ACL (access control list) system in my application though I can easily manage permissions on groups simply by fetching the session group id and restricting the access using the Auth component.
How is an ACL solution better then the approach I discussed above (restricting the group access based on group id) ?
How does implementing an ACL solution simplify things when it comes to managing access rights in your application ?
Till now I have learned that through ACL, permissions can be granted and revoked at runtime, but this functionality is also achievable without using an ACL.
I am very much confused about this, please help me understand the concept, when to use ACL and the benefits of using ACL in your web application.
I prefer to code with cakePHP v1.3 so it would be great if the explanation is given in context of cakephp but any help (language/technology independent) related to my question is greatly appreciated.
You must use ACLs (or an equivalent user permission mechanism such as literal database User and Permission tables) rather than groups if you need to control access to individual entities which vary dynamically. File systems attach ACL's to individual files since you don't want to create a separate group for each file. Database managers attach ACL's to databases, tables, views, stored procedures and whatnot for the same reason. Web servers deal with web applications in the same manner.
In a business application dealing with business entities, you may want to partition access to entities such as e.g. different sales orders, customers, products or divisions within your company, where not everybody is allowed to create/update or even read the same entities. For instance, when sales staff are in direct competition for bonuses, they don't want everybody else to see all the information on their CRM-stored prospects.
Usually, though, you want to keep your access mechanisms as coarse-grained as is humanly possible: groups are usually good enough. Fine-grained access control mechanisms have a tendency to grow complex, expensive, inaccurate and hard to use correctly. They may even decrease security, since administrative frustration encourages people to find clever workarounds...
I think that ACL technic for securising user access to ressources is usefull only for a typical or medium - sized application . for big applications like CRM or financial data warehouses , ACLs will fail to manage a very complex set of user / ressource couples , when the data increase in size , in type and in volume , the ACLs tables made for that purpose will increase too , which it make for me no sense to overload the database server with ACL Tables. There are many others technics used to install security access and permissions and privileges ... The use of ACL files instead does not sound bad but it is not a good idea as files may corrupt from time to time so data failure is over the risk to not have access to a file containing ACL rules or to access a non existing file or a lost one ... The only way to play with permission is to use the business tables used in the context or in the purpose of your application with relationships between your tables and some logic to add to your Service Side Scripts if you are under MVC Architecture or any else ... So Avoid using ACL for very big sized applications.

Resources