How to secure Business Objects

This post explains how you can secure your business objects in a model driven way, using the Imixs-Workflow engine.

Most applications deal with security in a functional way. This means that a business application typically defines different functional roles which are mapped to different users. For example let’s look on a simple Ordering System. In an Ordering System, we will have roles like

  • Order-Creator‘ – creating the order
  • Order-Approver‘ – validating and approving
  • Order-Executor‘ – execution

These roles are typical for such an business application and mostly tightly coupled to the corresponding business methods – e.g. createOrder(), approveOrder() and executeOrder(). This works well in a monolithic business application where you can control the security layers as also the business logic. But as more complex the business application becomes, also the enclosed security becomes more complicated. For modern application design, in addition, you often have to deal with external web services and business logic which need to be adapted easily to changing requirements. So this static security model leads into a hell of hard coded business rules or, what is worse, can no longer guarantee the security.

Using the Imixs-Workflow Engine

Using a workflow engine in general offers manifold opportunities to solve such a situation in a model driven way. With the Human-centric workflow engine Imixs-Workflow, the mapping between a function and a business role is done by the workflow model. So the business functions will be decoupled from the business process and can be designed in a more flexible way.

Create a Business Model

First of all we need to create a business model. Most workflow engines support the BPMN standard 2.0 (Business Process Model and Notation). With BPMN you can describe the different phases of our business process life-cycle:

bpmn-security01

You can create the business model using the Eclipse based modelling Tool Imixs-BPMN.

Definition of Business Roles

Now the important difference when modelling a business process is that you need to abstract the business roles. This is to ensure that you can decouple the business model from the functional programming. In our example, this means that we define logical business roles which are mapped to the real world persons involved into the process. So let’s assume that your project has defined the following departments:

  • Sales Department – creating orders
  • Management – approving orders
  • Finance Department – executing orders

These are the roles your business model has to deal with. With Imixs-BPMN you can map the roles directly into the process model:

bpmn-security02

In this example the roles are mapped to three different person groups which can change later during runtime. The person groups can be managed by the workflow system itself or by an external directory (e.g. LDAP).

The Access Control List (ACL)

Now as you have defined the business roles, you can map the roles to different tasks of your process model. Imixs-Workflow defines an ACL setting for each task a process instance can be assigned to:

bpmn-security03

The ACL of a process instance differentiates the following roles:

  • Owner – the responsible person of the process instance
  • Read Access – a reader can access the process instance
  • Write Access – an author can update the process instance

In our example above the ACL for the Task ‘Approve Order‘ grants a write access the Management department but only a read access to the Sales Department. The Finance Department is not yet allowed to access the task.

So a person which has no read access to a process instance (Finance Department) will be unable to search or access this instance. A person having write access (Management) will be allowed to process the current task. In addition an Owner will be assigned to the process instance so these persons will see the workitem in a personal tasklist.

To complete our example, you can now design the following responsibilities for our process:

  • Sales Team  -> create an Order
  • Management -> approves an Order
  • Finance Department -> executes the Order

These roles are now no longer granted on a functional level, but on the level of the business object (the process instance) which is managed by the workflow engine. This means that each process instance can have an individual ACL setting. The example model can be downloaded from here.

Calling the Workflow Engine

Still we have no mapping between our ordering application and the ordering process. So now it’s time to bring the workflow into our business application.

The Imixs-Workflow engine can either be embedded into the code or called via a rest service API. The following example shows how you can call the order-process using the embedded engine. The Imixs-JSF Sample application gives a excellent overview how to use this application as an template for custom projects.

Create a new Process Instance

First of all you need to create a new instance of your order-process which can be done in the createOrder() method.  Imixs-Workflow provides a generic value object holding business- and process-data. This object can be provided with the order data and information about the process model to create a new order instance:

@EJB
private org.imixs.workflow.jee.ejb.WorkflowService workflowService;
....
public String createOrder() {
  // create a new order item
  ItemCollection order=new ItemCollection();
  order.replaceItemValue("order-no","47-43");
  order.replaceItemValue("price",new Double(40));
  // assign the process model
  order.replaceItemValue("$processID",1000); // create order
  order.replaceItemValue("$modelversion","order-model-1.0.0");
  order.replaceItemValue("$activityID",10); // forward to management
  order =getWorkflowService().processWorkItem(order); 
  // get id 
  return order.getUniqueID(); 
}

This example creates a order-item with an order-no and a price. Next we assign the model-version and the initial task-id and call the event ‘forward‘ from our process model. The workflow engine will create a new process instance applying the ACL settings, defined by the model. Finally the engine returns an order object containing a unique-id to be used to access the order-item later

Update the Process Instance

Imixs-Workflow automatically controls the ACL of your order-item and stores the data together with processing information into a database. You can check the status of the new process instance by requesting the process instance and testing different workflow attributes managed by the workflow engine. Finally you can now update the process instance by calling the next ‘forward‘ event:

public void approveOrder(String orderID) {
   // load order...
   ItemCollection order = getWorkflowService().getWorkItem(orderID);
   if (order != null) {
     // check the new order process instance....
     String status = order.getItemValueString("txtworkflowstatus"); // returns the new status
     int taskID = order.getItemValueInteger("$processid"); // returns the current TaskID
     List writeAccess = order.getItemValue("$writeaccess"); // returns a list of all users with write access
     // check if current user has author access?
     if (order.getItemValueBoolean("$isauthor")) {
       // we can process the data
       order.replaceItemValue("$activityID", 10); // forward to accounting
       order = getWorkflowService().processWorkItem(order);
       // update ordering system....
     } else {
       // current user is not allowed to read this instance!
     }
   }
}

This example illustrates how the process data of our order instance can be used to verify the status and ACL for further processing. If the user is not allowed to read the order-item the method will return immediately. If the user is not granted to update the process instance an AccessDeniedException will be thrown by the workflow engine. Finally we forward the process instance to the Finance Department.

Conclusion

With the approach of the Imixs-Workflow engine you can decouple our business logic from hard coded security roles. The important part here is, that you do no longer need to assign a security role with methods into the code. Instead, you create a process instance managed by a workflow engine. The security is modeled in a BPMN process model and can be adapted easily to new requirements without the need to change the business functions. Instead that we secure our business methods by hard coded functional roles, we now secure our business objects. This is a powerful concept which extends the behavior of a business application and can bear also complex business logic.

Leave a Reply

Your email address will not be published. Required fields are marked *