Over a million developers have joined DZone.

Make Your Business Objects Secure

Here is everything that you need in order to get started making your business objects secure.

· Security Zone

Discover how to protect your applications from known and unknown vulnerabilities.

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 a 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 we 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, we 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 a Workflow Engine

Using a workflow engine offers manifold opportunities to solve such a situation in a model driven way. I will show this on the example of Imixs-Workflow, which is an open source human-centric BPM engine. Human-centric business process management means to support human skills and activities by a task orientated approach. 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 we can describe the different phases of our business process life-cycle:

Image title

This business model can be created using the Eclipse-based modeling Tool Imixs-BPMN.

Definition of Business Roles

Now the important difference when modeling a business process is that we need to abstract the business roles. This is to ensure that we 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 in the process. So let's assume that our enterprise has the following departments:

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

These are the roles our business model has to deal with. With Imixs-BPMN the roles can be mapped directly into the process model:

Image title

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 we have defined our business roles we can map the roles to different tasks of our process model. Imixs-Workflow defines an ACL setting for each task a process instance can be assigned to:

Image title

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, we 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 to 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 we need to create a new instance of our 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 = workflowService.processWorkItem(order);
  // get id
  return order.getUniqueID();
}

In this example we create 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

The workflow engine will automatically control the ACL of our order-item and stores the data together with processing information into a database. We 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 we can update the process instance by calling the next 'forward' event:

public void approveOrder(String orderID) throws AccessDeniedException, ProcessingErrorException, PluginException {
   // 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 a workflow engine we can decouple our business logic from hard coded security roles. The important part here is, that we do no longer need to assign a security role with business methods into the code. Instead, we 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.

Find out how Waratek’s award-winning virtualization platform can improve your web application security, development and operations without false positives, code changes or slowing your application.

Topics:
security ,workflow engine ,bpmn

Published at DZone with permission of Ralph Soika. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}