Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Security

An Application-Access Security Model


DEC95: An Application-Access Security Model

An Application-Access Security Model

Designing security systems based on job-related roles

Mark Robinson

Mark is a PowerBuilder consultant with Toronto-based Data Management Consultants (DMC), specializing in the delivery of custom Oracle solutions. Mark can be reached at [email protected].


One of the fundamental roadblocks at the beginning of any client/server development project is implementing access security. From user accounts and menu accessibility to managing individual controls on a window, application security is usually implemented as a mishmash of unrelated, nonuniform, hardcoded, poorly considered attempts to block unwanted access to an application's functionality. In this article, I'll present an integrated, generic, reusable model of network security based on object-oriented concepts. To illustrate these concepts programmatically, I'll provide examples written in PowerBuilder that demonstrate the flexibility and power of this model. The code is provided only to demonstrate communication methods between objects, not as a fully coded security handler.

As client/server and network technologies grow, so does the target user group of an application. Applications are continually breaking the traditional limitations of being focused on specific functional areas. The current trend is to develop enterprise-wide applications with a large, heterogeneous user community. At the same time, companies are attempting to provide access to their data on a need-to-know basis. There is an ever-growing need to approach application/data accessibility as a concept on its own.

Security Goals

Access-security implementations have two main goals. The most important is to prevent access to private information by unauthorized users. This can be accomplished by blocking access to an application, module, window, or even a control of a window. The second goal is to make the application easier to use by not showing users functionality that does not have a direct bearing on their job. This allows large applications to appear smaller and easier to use.

From a practical point of view, a security implementation must function as an integrated unit. But during the analysis and design phases, most projects focus only on what data must be secure, not how to secure it. When the development phase starts, security is implemented on an ad hoc basis, with each developer being responsible for the security of his or her own modules.

The underlying concept of this article is that security should be integrated into the functional foundation of an application. Developers will interface with a common security object to limit accessibility to their modules. This object will know how to inform other objects about the current user's accessibility privileges.

Object Leveling

Object-based applications form a natural hierarchy of objects. Application objects contain window objects, which contain control objects. From the perspective of a security model, all of these objects can be leveled, thus allowing object-based security. Object leveling is the process of manipulating all different classes of objects in the same manner by creating a common interface. Thus, the security handler interacts with all windows, child windows, buttons, and controls in the same way; it does not differentiate between different classes of objects. Objects with very specific hierarchical requirements can be handled by each object individually. The security handler assumes the role of informant, informing objects of initial settings and mode changes.

Security-Model Overview

In this security model, a relationship is formed between business-oriented tasks and application-oriented objects. For our purposes here, I'll use two groupings: roles and objects. Users can have one or more roles within a company, and a role can be performed by one or more users. Objects can be manipulated by one or more methods, and methods can be applied to one or more objects; see Table 1.

A relationship between roles and objects is formed to define the methods used when the object is instantiated. This relationship defines the accessibility and the level of control that a role has over an object.

Designing a security system based on your own job-related roles allows your company to use a common, enterprise-wide definition of data accessibility. A warehouse clerk, for instance, can only update product inventory. Designing a security system based on a set of your own common business objects allows you to manipulate data in a consistent manner from any application. A product-inventory object can be made accessible through any application and will always look and behave the same way. By mapping roles to objects, your company will benefit from a single security database with which all applications will interact, as shown in Figure 1.

Security-Handler Components

The security handler is a self-contained object with two broad areas of responsibility. First, it must have the ability to determine a user's roles and accessible objects from the security database. Because this database is intended to be corporate wide, it makes sense to maintain the security data in its own database. Security settings are generally static, so the security handler will read in all available information for this user. This is an implementation choice that can be made during the build phase. The trade-off here is local-memory storage requirements versus application speed.

Secondly, the security handler must be able to instruct objects to apply the defined methods at the appropriate time. The security handler has two methods of communicating with objects. The first and most common is Object Direct, which is generally used when the object is first created and is about to be displayed to the user; see Figure 2. Using this method, the security handler informs a specific object about the rights and privileges of the current user. The object will then configure itself accordingly. The second method of communication is Object Broadcast, which allows the security handler to make application-wide announcements; see Figure 3. Usually, these announcements involve state changes within an application, such as a window going into update mode. The security handler will broadcast a state-change message to all parent windows, which will then process the message and inform all of their dependent windows and controls.

Security Database

The database for this model contains the relationships formed between roles and objects. The database is enterprise wide; if built carefully, these relationships are valid for any application. For Object Direct communication, the required fields are Role Name, Window Name, Control Name, Method Name, and Attribute Value. Object Broadcast tends to be application specific and does not rely on a database. When the application is started, the user's roles are used to load the security data. If a user has more than one role, there may be overlap in the security data. This is especially true for supervisory and management roles. To resolve the overlap, the loading process should allow the roles with the greatest accessibility to dominate. For example, a user may perform clerk duties but also be a manager. The clerk role would prohibit deletion, but the manager role would allow it, so the database should allow the user to have delete capability.

Using PowerBuilder

To implement this model, all of your objects must be inherited from a base object class that contains the necessary communication interfaces. The base class for windows will be called w_base. This class provides the necessary object leveling for the security handler. In general, it is poor programming practice and counter to all object-oriented concepts for one object to directly manipulate attributes of another. For practical purposes, you may find it necessary to limit this rule to window boundaries. In other words, one window is prohibited from directly altering attributes for objects in another, but a window may directly alter the attributes of objects it itself contains.

Each object class will have two local functions--f_Set() and f_Get()--to process information about object attributes. f_Set() will be used as the primary entry point for each object. If one object needs to tell another object to do something, it uses this function. Listing One is one way to implement f_Set(). On the other hand, f_Get() (see Listing Two) is used by other objects to ask questions about attribute values and operating states. Using these two functions, the security manager can control the behavior of objects by assuming the role of informant.

PowerBuilder provides customizable User Objects; see Table 2. The security handler will be implemented as a nonvisual User Object with functions and structures defined within it. The security handler will have two registration functions, f_Register() and f_DeRegister(), and two communication functions, f_Direct() and f_Broadcast().

  • f_Register(). When a window is opened it must register itself with the security handler. The registration process allows the security handler to store information about the window, and is mainly used for Object Broadcast. Listing Three illustrates this function.
  • f_DeRegister(). When a window is closed, it must inform the security handler. The deregistration process allows the security handler to remove information previously registered; see Listing Four.
  • f_Direct(). During the process of instantiating a window, this function is called to instruct the object to execute specific methods to control user access. In addition, this function can be used for localized mode changes; see Listing Five.
  • f_Broadcast(). Certain conditions may arise during program execution that require that all objects be notified of a specific event or situation. This function informs the top-level windows of the change, and each window is responsible for informing any subordinate objects; see Listing Six.
As each window opens, it interacts with the security handler to configure itself. The code for the interaction resides in the W_BASE Open event of the base window object because every window must communicate with the security handler; see Example 1(a).

As each window closes, the security handler needs to deregister it. Example 1(b) shows the W_BASE Close event for the base window object.

Managing the Security System

To manage the security system, you will need to write an application to define roles, browse object libraries, match methods against objects, and store the access privileges in your security database. Clearly, having common objects and roles already identified and defined is beneficial. However, building the security-management system itself is beyond the scope of this article.

Implementation Strategies

During the development phase of a project, all developers dislike being hampered by application-security restrictions. This security manager can be particularly annoying because it is both object and role based. I have found it useful to have a temporary security manager that merely says "yes" to everything. This means that you must have a specific security test during your application-testing phase (you should, anyway). When it is time to create an executable program, the real security-manager object can be substituted without having to change any code.

Another factor to consider is the proportion of total screens that require security. If most screens are commonly available to all users, it should be assumed that all screens are initially active and the security handler must disable them based on security. If most screens are not commonly available to all users, it should be assumed that all screens are initially inactive, and the security handler must enable access to screens based on the security settings.

Providing communication between objects has many benefits beyond access security. Using this model as a foundation, you can create an entire communication infrastructure embedded within the base of objects of your development environment.

Figure 1: A shared security database.

Figure 2: Security handler communicating via the Object Direct method.

Figure 3: Security handler communicating via the Object Broadcast method.

Table 1: PowerBuilder user objects.

<b>Object         Description</b>
Custom            A collection of standard PowerBuilder controls that you
                       create to perform a specific operation, such as a
                       tab-folder object or a customer-profile maintenance
                       utility.
External          An object that contains controls defined by an external
                       DLL. When using multiple development packages, you can
                       create common objects in a DLL and access them through
                       external objects. Other possibilities include
                       communication or network objects.
Nonvisual        This type of user object encapsulates functions and
                       attributes but is never visible. Used primarily to
                       create specific processing functionality bundled into a
                       single entity such as a window-manager object.
Standard         A preexisting, customizable PowerBuilder control such
                       as a button or edit control. By default, its attributes
                       and events are initialized to the standard PowerBuilder
                       settings for that object. Used primarily to create
                       object classes for standard PowerBuilder objects.
VBX                 PowerBuilder supports Visual Basic controls with special
                       attributes and events. You must create objects using
                       Visual Basic or purchase them as object libraries.
Table 2: PowerBuilder customizable User Objects.
<b>Term        Definition</b>
Role              An identifier for a definable set of business-related
                     activities that can be used to classify employees into 
                     workgroups. More than one employee may perform a specific 
                     role, and more than one role may be performed by a 
                     specific employee. Examples of role designations include 
                     accounting clerk, production foreman, and VP sales.
Method          Describes an operation used to manipulate an attribute
                     of an object. More than one method may affect the same
                     attribute differently. Examples of methods include
                     <I>SetVisibility</I> and <I>SetValue</I>.
Object           A discrete unit containing its own attributes.
                     Objects can be hierarchical as long as the composite
                     object has attributes specific to itself that are not
                     obtained from its component objects. Examples of
                     objects are windows, buttons, and scroll bars.
Attribute      A single unit of information used to describe
                     a specific characteristic of an object. Examples of
                     attributes are visible, horizontal position, and font.
Example 1: (a) W_BASE Open event; (b) W_BASE Close event.
(a)
// The window (this) registers itself as a parent

SecurityHandler.f_Register(This, True)

// The window requests the security handler to provide access information

SecurityHandler.f_Direct(This)

(b)
// The window (this) informs the security handler that it is closing

SecurityHandler.f_DeRegister(This)

Listing One

Boolean f_Set(sObject, sMethod, sAttributeValue)
Parameters      Description
sObject     A string identifying the object that is to be modified.
sMethod     A string identifying the name of the method to be used to 
                                              modify and attribute of sObject.
sAttributeValue A string representation of the new value to set by sMethod.
Script
CHOOSE CASE sMethod
    CASE 'SHOW'
        CHOOSE CASE sObject
            CASE 'CB_SAVE'
                cbSave.Visible = TRUE
            CASE 'CB_DETAIL'
               cbDetail.Visible = TRUE
        END CHOOSE
    CASE 'HIDE'
        CHOOSE CASE sObject
            CASE 'CB_SAVE'
                cbSave.Visible = FALSE
            CASE 'CB_DETAIL'
                cbDetail.Visible = FALSE
        END CHOOSE
    CASE 'TEXT'
        CHOOSE CASE sObject
            CASE 'CB_SAVE'
                cbSave.Text = sAttributeValue
            CASE 'CB_DETAIL'
                cbDetail.Text = sAttributeValue
        END CHOOSE
END CHOOSE
RETURN TRUE

Listing Two

String      f_Get(sObject, sAttributeName)
Parameters      Description
sObject     A string identifying the object that has the desired attribute.
sAttributeName  A string identifying the attribute whose value is requested.
Script
string  sAttributeValue
CHOOSE CASE sAttributeName
    CASE 'VISIBLE'
        CHOOSE CASE sObject
            CASE 'CB_SAVE'
                IF cbSave.Visible = TRUE THEN
                    sAttributeValue = 'TRUE'
                ELSE 
                    sAttributeValue = 'FALSE'
                END IF
        END CHOOSE
    CASE 'TEXT'
        CHOOSE CASE sObject
            CASE 'CB_SAVE'
                sAttributeValue = cbSave.Text
           CASE 'CB_DETAIL'
                sAttributeValue = cbDetail.Text
        END CHOOSE
END CHOOSE
RETURN sAttributeValue

Listing Three

Boolean     f_Register(wRegistrant, bParent)
Parameters  Description
wRegistrant A window inherited from base window class, w_base. This window
                                   is to be registered by the security handler.
bParent     A boolean flag indicating if this window is a top level window.
Script
MaxWindows ++
Registered[MaxWindows].Window = wRegistrant
Registered[MaxWindows].bParent = bParent
RETURN TRUE

Listing Four

Boolean     f_DeRegister(wRegistrant)
Parameters      Description
wRegistrant     A window inherited from base window class, w_base.  
                    This window is to be de-registered by the security handler.
Script
int i
FOR i = 1 to MaxWindows
    IF Registered[i].Window = wRegistrant THEN
        IF i = MaxWindows THEN
            MaxWindows --
        ELSE
            Registered[i].Window = Registered[MaxWindows].Window
            Registered[i].bParent = Registered[MaxWindows].bParent
            MaxWindows --
        END IF
    EXIT
    END IF
NEXT
RETURN TRUE

Listing Five

Boolean     f_Direct(wTarget)
Parameters      Description
wTarget     A window inherited from base window class, w_base. This window
                defines the target for the security handler. In most cases, a 
                window will request security information about itself.
Script
int i
FOR i = 1 TO MaxEntries
    IF ClassName(wTarget) = Security[i].sWindowName THEN
        wTarget.f_Set(Security[i].sControlName, 
                        Security[i].sMethodName,& Security[i].sAttributeValue)
    END IF
NEXT
RETURN TRUE
Notes: MaxEntries is an instance variable in the security handler 
identifying how many entries were loaded from the security database.
The Security array is a structure containing the window names, control 
names, method names, and attribute values that were loaded from the security 
database.

Listing Six

Boolean     f_Broadcast(sMessageId, sMessageValue)
Parameters  Description
sMessageId  A string identifying a pre-defined message to be broadcast.
sMessageValue   A string containing a value (if necessary) to elaborate on 
                the message. This parameter is used if there is a variable 
                component to the broadcast message.
Script
int i
FOR i = 1 to MaxWindows
    IF Registered[i].bParent = TRUE THEN
         Registered[i].Window.f_Set("BROADCAST", sMessageId, sMessageValue)
    END IF
NEXT
RETURN TRUE
Notes: MaxWindows is an instance variable containing the number of windows that are currently registered.
The Registered array is a structure containing a reference to each registered window and a boolean flag that is TRUE if the window is a parent level window.


Copyright © 1995, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.