Check Security Authorization
Because each system we build has custom security requirements, there is no way to implement one security model and apply it to all systems. Instead the framework supports extensibility points as part of the command and query architectures.
But before you go there, you’ll need to flesh out the requirements for security and build the necessary database tables.
Some important questions to answer regarding security requirements:
- What are the roles?
- Do users need to be granted/denied access to specific types of data? (i.e. can all users access all entities)
- Do users need to be granted/denied access to specific data (e.g. have access to one division, but not another division)
- What are the different rights that can be assigned to each role (very convenient if you can associate them one-to-one with biz commands)
- Do different roles need to be disallowed from different client apps?
- Who will manage security roles? How will they do this?
- Who will manage rights? How will they do this?
After understanding that, the next step would be to create the necessary database tables to support those requirements, populate them with data, and build some queries or stored procedures to allow you to ask the necessary questions of the security system. After all that, then we can wire up to the security system in the command and query architecture.
There are two different ways to apply security.
- Apply security on a per command basis
- Apply security on a per entity basis
Apply security on a per command basis
For Add, Edit, and Delete operations you will apply security on a per command basis. In this case you want to check security ONCE per command execution.
For each of your commands that need security do the following:
public override bool CheckSecurity()
{
}
Fill in the method guts with a query that checks whether the user has permission to execute this command OR has permission to execute this command on this entity. For example, you might have a system that allows for deleting of users. In one scenario, only admins can delete users. In that case, simply check whether the currently logged in user is an admin in the CheckSecurity method. In another scenario, only the user can delete themselves. In that case, check whether the user that is about to be deleted is the currently logged in user. In both scenarios we are checking security ONCE per command execution.
In theory you could apply this type of security checking on Get methods too since they operate on exactly one entity, however, see below for a better option.
Apply security on a per entity basis
For Get and GetAll, we are performing read operations on 1 or more records in the database. It is not efficient nor practical to do that checking in the command layer. Instead, checking is done in the query layer.
You will need to extend the code generated queries using partial classes. These partial classes should be placed in the /Queries/Extended folder in the Model project. You will typically override the GetAll method to include filters that apply security correctly. Note, that the Get method internally calls the GetAll method so you can limit your security settings to a single location and read security will be applied in a uniformed way everywhere.