Authentication and Access Control Package

The Morfik User Authentication and Access Control package provides the required functionality to secure a Morfik website against unauthorized use. In addition, it provides a number of ready-to-use widgets and forms that make securing and subsequent management of a website extremely simple. It should be noted that this package, while providing a moderate level of security to protect against unauthorized use, does not provide protection against malicious attacks.


How Do I: Secure my Morfik Applications?

This video shows how you could use the Authentication and Access Control Package to ensure that all aspects of your application security are covered. Learn how to add the security package to your project from scratch and include pre-built security widgets for different security related tasks.


The player will show in this paragraph

Demo video of the Morfik Authentication and Access Control Package


package-view.png
package-down.png

A Quick Walkthrough

To use the Morfik User Authentication and Access control package simply add the package to the project that you wish to secure by utilizing the “Used Packages” command on the project ribbon, or simply drag the package file onto the application main client area. Once added a number of widgets will appear on the home ribbon when the form designer is active. These widgets can be placed on application forms and provide immediate functionality without the need for coding or configuration of their properties. Read more...

Web Application Security – A Technical Overview

By definition all web applications are multi-user systems with a central repository of resources and a common point of access. It is therefore necessary to provide a mechanism through which the identity of a website visitor can be determined. Once identified, it is highly desirable to be able to control and limit visitors' access to application resources. This requires a system for “authenticating” a user as well as “assigning rights and privileges” that determine a user’s level of access to application resources.

User authentication requires the user to register with the system and choose a username and password which can later be used to identify the user. When a registered user visits the site and attempts to access resources that are protected, the application would need to prompt the user to login in order to determine the identity of the user. Once username and password are verified and the identity of the user is established then a session record with a unique ID (SessionID) is created and is stored in a session table. All subsequent requests from the same user (that follow within the same browser session) will carry this unique ID which will provide a convenient and also a safe way to establish the user’s identity throughout the remainder of the session (until the user logs out or the session record expires).

Once a user identity is established, either through username and password or through the SessionID, then the system will select a subset of access rules that are relevant to both the user and the resource that is being accessed. Then the rule with the highest priority is chosen to determine whether access should be allowed or denied.

Securing Project Items

It is important to know that adding the security package by itself does not secure your application. Rules must be defined in order to ensure your application content is protected. Otherwise all content within your application will be accessible to all. (The only part of your application that does not require further protection is the content of the security package itself. The content of the security package is already protected through built-in rules. The tables used inside the security package are not published and are therefore implicitly secure).

Before diving-in and starting to add security rules it might be a good idea to step back and adopt a general strategy for meeting the security requirements of your application. Depending on the level of sensitivity of the content within your application there are two general approaches that can be adopted:

  1. Optimistic approach - access to all resources is available by default. Rules are defined to limit access.
  2. Pessimistic approach - access to all resources is denied by default. Rules are defined to allow access.


The first approach is more suitable for applications that are external facing or applications that provide content that is not sensitive, such as public websites. The second approach provides much tighter security and is suitable for applications that are internal-facing or applications that have highly sensitive content such as corporate/business applications.

The first approach is easier to define rules for. The basic approach is to identify resources that need to be protected and define appropriate rules to secure them.

The second approach relies on a global rule (i.e. lowest precedence) being defined that denies access to all resources.

Note: If unaccompanied by some higher precedence rules for anonymous users, a global rule that denies access to all can make the application dysfunctional - even the site administrator would not be able to access the application! Such rules must ALWAYS be accompanied (or preferably preceded) by a set of rules that are defined for anonymous users and that allow minimum access so the application can start and get to a point where login is possible.

Providing “minimum access” is where the second approach gets somewhat complicated. The minimum resources required for an application to start successfully and get to the point where a user can login vary from one application to another.

One common way to make this tractable is to make the application’s home page comprised of a single form that contains an instance of the login widget. It is not surprising that a login form as the home page is the common face of most high security web applications.

Defining a single rule that allows access to the login form for anonymous users is a good start but we still need to define rules that allow core JavaScript files as well as the main html file to be accessed by anonymous users so the application can make a start. There might also be a need for additional rules that allow for images or other resources that are used within an application's home page.

One way to identify all these resources is to run the application from within the Morfik IDE and then view the HTTP panel and make note of all resources that are accessed. Then define rules to provide access to anonymous users for all these resources (see Figure 14 Minimum Resources Required to Start an Application).

Note: The administrator is considered by the system to be an anonymous user until he/she has had the opportunity to login.


security-figure14.png
Figure 1: Minimum Resources Required to Start an Application


Note: It is highly recommended that you do not add global rules that deny access in a general way when the application is live as it could bring the site down. If this ever happens, there is no easy remedy except to manually remove the rule record from the database file using some kind of database utility. As such it is advisable that you test such rules during development and make sure that the security administration section of your application is always accessible by the site administrator.
Protecting Tables and Queries
Protecting Forms and Reports
Protecting Web Methods and Modules
Protecting Published URLs
Protecting Custom Requests

Protecting Data in Transit using SSL

Whilst user authentication and access control provides protection against unauthorised use, additional measures must be taken to protect application resources after they leave the server and while in transit before arriving in the user’s browser. The most common way to protect data in transit is to use SSL (Secure Socket Layer) through the use of HTTPS protocol. When HTTPS protocol is used, data is encrypted during transit and therefore protected against eavesdropping or other similar attacks.

The HTTPS protocol is considerably slower than the standard HTTP protocol. Consequently it is desirable to only use HTTPS when requesting resources that are sensitive. While this is easily implemented in traditional page-centric web applications, in Morfik (and other Ajax systems) the implementation turns out to be more complicated due to browsers’ cross-domain/cross-protocol restrictions. These restrictions mean that a Morfik application is not able to selectively choose HTTPS protocol. In other words the use of the HTTPS protocol is an all-or-nothing affair in a Morfik application. There are two ways to go about finding a solution for this problem.

The first solution is to separate that portion of your application that requires SSL by placing the relevant project modules in a separate project which is accessed exclusively using the HTTPS protocol.

The second approach is to get around the browsers’ cross-domain restriction. One common technique is to use a cookie to store the result of a request that is made on the HTTPS protocol and then access the cookie from application’s main code (which would have downloaded using the HTTP protocol). This involves setting up a timer, sending the request using the HTTPS protocol and then polling for a cookie that signals the return of the request and also holds the response from the server. The server code that handles the request must prepare the response in such a way that upon arrival it will get written into a cookie that carries the actual response.

Protecting against malicious attacks

Securing a web application is an open-ended topic and has many aspects that are well outside the scope of this document. It is important to note that securing a Morfik website using Morfik User Authorisation and Access Control package does not protect against malicious attacks such as Denial-of-service attack or Dictionary attack.

The scope of security measures that must be taken to protect against malicious attacks goes well beyond application-level security. For example, running your Morfik website and its database server behind a firewall, minimising the number of services running on the server and limiting it to those that are required for running the application and the database server, and keeping servers up-to-date with the latest patches and software releases, are amongst the many measures that are important in a broader context of security.

Password Recovery

User information is stored in the mfk_secUserAccts table. Users’ passwords are also stored in the same table in MD5 hash format. MD5 provides added security making it not possible (using conventional methods as MD5 is not an encryption method) even for the administrator to retrieve user passwords, as such password recovery is not possible! However when a password is forgotten, the system can generate a new password replacing the old one. The system will invoke the OnResetPassword event (which must be assigned programmatically in the current version of Morfik as there is no visual designer for the package object itself). The event handler for this event should be assigned to OnResetPassword which is a global variable in the mfk_secUtil module. Again a good place to make this assignment is in the application On Start event. Below is a code snippet that demonstrates how to send an email to a user who has requested his/her password to be reset.


FX Code

Uses
mfk_secUtil,
SystemInternet;
 
Procedure HandleResetPassword(Username, FirstName, LastName, Email : String; 
                              Var Cancel : Boolean; Var NewPwd : String);
Var
    MailText : TStringList;
    ErrorMsg : String;
Begin
    MailText := TStringList.Create;
    Try
        MailText.Add('Dear ' + FirstName + ',');
        MailText.Add('');
        MailText.Add('Your account password has been reset to:');
        MailText.Add('');
        MailText.Add(' Username: ' + UserName);
        MailText.Add(' Password: ' + NewPwd);
        MailText.Add('');
        MailText.Add('It is strongly advised that you change your password when you next login!');
        MailText.Add('');
        MailText.Add('Thank you,');
        MailText.Add('');
        MailText.Add('Support');
        SendEmail('my.smpt.com', EMail, 'me@mycompany.com', 'Password Reset Confirmation', 
                   MailText.Text, 'MySMPTUserName','MySMTPPwd',ErrorMsg);
        Cancel := Not ErrorMsg.IsEmpty;
    Finally
        MailText.Free;
    End;
End;
 
Procedure Project52XApp.XAppStart(Sender: TObject);
Begin
    OnResetPassword := @HandleResetPassword;
End;

Protecting your application programmatically

There are occasions where you might want to protect your application by writing code rather than relying on rules. The need for this usually arises when you have a predetermined role within your application that, as the developer, you want to hard-code into your application and one which you do not want the site administrator to be able to change. A good example of this is the Admin role in the security package. All the Web Methods (non-visual) defined in the security package are protected programmatically rather than through rules.

The way to programmatically protect a resource is to check if the request is from a user that is assigned to the role that has been granted the right to access the resource. The following code demonstrates how this could be done:


FX Code

Uses
mfk_secUtil;
 
Procedure Index.WebFormBeforeExecute(Sender: TWebDocument; Var PContinue: Boolean);
Begin
    With SecurityProviderClass.Create(HTTPServer) Do
    Try
        If Not IsCurrentUserInRole('TargetRole') Then
            Raise Exception.Create('Access Denied!');
    Finally
            Free;
    End;
End;

‘TargetRole’ is the role that the user is expected to be assigned to in order to gain access to the requested resource. For forms and reports this code should be placed in the OnBeforeExecute event-handler and for Web Methods it could be placed as the first statement inside the Execute method.

Note: HTTPServer is a field of the Form object that points to the current request server. The same field exists for tables, queries and reports. For Web Methods however this field is called SoapServer.

Login Manager

The LoginManager is a global object introduced by the security package. It resides in the browser side of your application and is responsible for interactions that take place between the browser side and the server side of the security package related to login activities. This object holds information about the current user who is logged in and has a number of useful methods. These include:

Properties:

  • SessionID – The current session ID created in response to the user login request.
  • FirstName – Current user’s first name.
  • LastName – Current user’s last name.
  • Username – The username used to login.
  • Email – Current user’s email address
  • UserID – Current user’s account record ID
  • UserRoles – List of roles that the current user is assigned to.

Methods:

  • UserLoggedIn – Returns true or false depending on whether a user is currently logged in or not.
  • CloseSession –Closes the current session by logging the current user out and removing the session record from the session table.
  • Login – Calls a web method to authenticate a user by sending a username/password combination and requesting a new session to start.
  • LoginActionPending – Returns true if a login request is currently in progress.
  • RefreshAccoutDetails – Refreshes the account details for the current user.
  • IsUserInRole – It checks if the current user is assigned to a given role.
  • RegisterEventHandler – Registers an event handler for ‘login’ or ‘logout’ events. Once registered the event handler will be called whenever a user is logged in or logged out.

This LoginManager is implemented in the mfk_secClient module.

Receiving Global Login/Logout Notifications

There are often circumstances where you might want to show or hide certain parts of your application user interface depending on whether a user is currently logged in or the role of the current user. In these situations the best way is to register to receive notification independent of the context in which the actual login/logout occurs. Otherwise you have to make sure that from every place that the user can login/logout you will call the appropriate functions to update the user interface or perform other similar actions.

To receive notification about user login/logout activities independent of the context in which the event occurs, you need to register an event handler with the LoginManager. This can be done using the RegisterEventHandler method as shown below:


FX Code

Uses
    mfk_secClient;
 
Procedure Content.HandleLogin;
Begin
    ShowMessage('User just logged in');
End;
 
Procedure Content.HandleLogout;
Begin
    ShowMessage('User just logged out');
End;
 
Procedure Content.WebFormReady(Var Ready: Boolean);
Begin
    LoginManager.RegisterEventHandler('Login', GetMethodPointer(Self,@HandleLogin));
    LoginManager.RegisterEventHandler('Logout',GetMethodPointer(Self,@HandleLogout));
End;

Custom Security Provider

With the Morfik User Authentication and Access Control package it is possible to customize the actual implementation of user authentication and/or the storage of the user information. This is made possible through the TSecurityProvider class. The TSecurityProvider class defines an abstract interface between the implementation of the security functions and the rest of the package.

The built-in security provider that comes with the package uses the Firebird database for storing user information and implements user authentication within the TFBSecurityProvider class. This class is a direct descendant of the TSecurityProvider class.

To implement customized security, a class must be derived that descends from the TSecurityProvider class (similar to TFBSecurityProvider) and provides storage and the actual implementation of all abstract methods that are defined in TSecurityProvider class.

To put into effect the custom security class, the global variable SecurityProviderClass in the mfk_secUtil module must point to the new class.

Impact of Security Checking on Application Performance

Depending on the type of application, the number and nature of rules and the extent that HTTPS protocol is used in an application, performance may be impacted by the introduction of extra security layers. This is mostly due to the additional processing performed on the server side for every request and the browser’s reduced ability to use cached content (requests for identical resources carry different security IDs when a new session starts and hence are treated as different content by the browser).

To minimise the impact:

  1. Keep the total number of rules to a minimum
  2. Use rules that are specific in their resource scope (minimise the number of rules that use “All” for resource type).
  3. Prompt for login only when protected resources are accessed. Do not force users to login at the start of your application.
  4. Minimise the use of HTTPS protocol.

Once the security package is installed, it adds a number of security-related widgets that come as part of this package. These widgets are already pre-wired to the back-end functionality. All you need to do is to place them on your application forms – there is no need for coding.

Login Bar Widget
Login Name Widget
Login Status Widget
Login Widget
Change Password Widget
Password Recovery Widget
Create User Widget

See Also


Back to top