Tutorial 40: How to implement a Secure Login/Logout Mechanism

This tutorial explains how to implement a secure login/logout mechanism for a Formspider application.

The sample application described in this tutorial contains two screens. The first one is a login screen containing “Username” and “Password” fields and a “Log In” button. The second one is a simple welcome screen containing a welcome message textLabel, a “Log out” hyperLink and a “Dummy Request” button. This tutorial explains how you can ensure a secure log in when the “Log In” button is pressed and a secure log out when the “Log out” hyperLink is clicked.

Why you need to Secure Login/Logout?

Whenever a Formspider application opens, Formspider automatically generates a new session id and associates it with the application. This session id remains fixed during session’s lifetime unless it’s changed by the developer. However, especially to prevent security vulnerabilities like session hijacking, developers often need to change the session id without losing the whole session as soon as a user logs in.

Similarly, developers also need to change the session id when a user logs out. In this case, they must also delete the whole session (Formspider session variables) in addition to change the session id.

Formspider solves these demands by providing specific APIs which allow the developer to;

  • Change the session id without losing the whole session
  • Restart the application by reopening it with a new session id and deleting the old session

Implementing the Secure Login/Logout Mechanism

Open Formspider IDE and click “New Application” under the “File” menu. The “New Application” dialog shows up. Enter “secureLoginLogout” as the name of the application and “HR” as its Datasource Schema name.  If you are using Formspider Online, you do not need to enter database schema name since your account is already configured to use your online database. Leave other fields empty and click “OK”. This creates the “secureLoginLogout” application with a default mainframe (called “mainFrame”) and a default panel (called “mainPanel”).

Create a panel which contains the “Username” and “Password” fields and the “Log In” button. Expand the “Containers” accordion, select the “Panels” node in the navigation tree and click the “+” button to create a new panel. Alternatively, you may right click the “Panels” node and select the “New” menu item from the pop-up menu. The “New Panel” dialog shows up. Enter “loginPanel” as the name of the panel. Click “OK” to create and open the panel in the editor.

Creating “loginPanel”

Add a textField labeled “Username”, a passwordField labeled “Password” and a “Log In” button to the “loginPanel”;

<panel font-size="14">
  <tableLayout cellSpacing="10">
    <row/>
    <row heightPolicy="Dynamic">
      <cell columnSpan="3" hAlign="Full" vAlign="Full">
        <textLabel font-size="20" label="Log in to the Tutorial Application"/>
      </cell>
    </row>
    <row height="1"/>
    <row height="30">
      <cell width="80" hAlign="Left" vAlign="Full">
        <textLabel label="Username:"/>
      </cell>
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textField name="username" autoComplete="Y"/>
      </cell>
    </row>
    <row height="30">
      <cell hAlign="Left" vAlign="Full">
        <textLabel label="Password:"/>
      </cell>
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <passwordField name="password"/>
      </cell>
    </row>
    <row height="30">
      <cell/>
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <button font-color="#303030" font-style="Bold" label="Log In"/>
      </cell>
    </row>
    <row height="1"/>
    <row/>
  </tableLayout>
</panel>

Include the “loginPanel” to the “mainPanel”. Expand the “Panels” node under the “Containers” accordion and double-click the “mainPanel” to open it in the editor. Edit the panel XML as following;

<panel>
  <borderLayout>
    <cell docking="Center" name="cell_center">
      <include panelName="loginPanel"/>
    </cell>
  </borderLayout>
</panel>

Create a new panel and enter “welcomePanel” as the name. This panel contains a welcome message textLabel, a “Log out” hyperLink and a “Dummy request” button which will be used while experimenting with the login mechanism at the end of this tutorial.

<panel font-size="14">
  <tableLayout cellSpacing="5">
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <hyperLink font-color="Blue" text-align="Right" label="Log out"/>
      </cell>
    </row>
    <row>
      <cell hAlign="Full" vAlign="Full">
        <textLabel label="Welcome to the Tutorial Application. You may securely log out using the link above." text-align="Center"/>
      </cell>
    </row>
    <row>
      <cell hAlign="Full" vAlign="Center" childHeight="100">
        <button label="Dummy request">
          <events>
            <buttonPress/>
          </events>
        </button>
      </cell>
    </row>
  </tableLayout>
</panel>

Note that any action is not assigned to the buttonPress event of the “Dummy request” button. This usage means that pressing this button triggers a dummy (null) request.

When “Log In” button of the “loginPanel” is pressed you should validate the “Usename” and “Password” values and change the session id if the user is successfully logged in. To achieve this, create a Formspider action which will be fired when “Log In” button is pressed.

In your datasource schema, create a package called  “secureLoginLogout_pkg” and open your newly created “secureLoginLogout_pkg” package in your favorite PL/SQL editor. Add a procedure named “logIn” and ensure that the procedure is exposed in the package specification. This procedure uses api_component.getValueTX API to retrieve the values entered in “Username” and “Password” fields. If both of these values are not null, it calls the api_session.authenticate API to change the session id without losing the whole session. Please note that this API automatically generates a new session id and associate it with the current application.

After authenticating the session, this procedure uses the api_panel.addPanel API to display the “welcomePanel” on the screen.

procedure logIn is
  v_userName_tx varchar2(4000);
  v_password_tx varchar2(4000);
begin
  v_userName_tx := api_component.getvaluetx('loginPanel.username');
  v_password_tx := api_component.getvaluetx('loginPanel.password');
  if v_userName_tx is not null and v_password_tx is not null then
    -- change the session id
    api_session.authenticate;
    -- navigate to the welcome screen
    api_panel.addpanel('mainPanel', 'cell_center','welcomePanel');
  else
    api_application.showpopupmessage('Invalid username or password');
  end if;
end;

In Formspider IDE expand the “Actions” accordion, select the “Actions” node, click the “+” button to create a new action. Alternatively you may right click the “Actions” node and select “New” from the pop-up menu. The “New Action” dialog shows up. Enter “logIn” as the action name and “secureLoginLogout_pkg.logIn” as the procedure. Click “OK” to save your action.

Open the “loginPanel” in the editor. Add a buttonPress event to the “Log In” button triggering the “logIn” action, the panel XML should look like;

<panel font-size="14">
  <tableLayout cellSpacing="10">
    <row/>
    <row heightPolicy="Dynamic">
      <cell columnSpan="3" hAlign="Full" vAlign="Full">
        <textLabel font-size="20" label="Log in to the Tutorial Application"/>
      </cell>
    </row>
    <row height="1"/>
    <row height="30">
      <cell width="80" hAlign="Left" vAlign="Full">
        <textLabel label="Username:"/>
      </cell>
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textField name="username" autoComplete="Y"/>
      </cell>
    </row>
    <row height="30">
      <cell hAlign="Left" vAlign="Full">
        <textLabel label="Password:"/>
      </cell>
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <passwordField name="password"/>
      </cell>
    </row>
    <row height="30">
      <cell/>
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <button font-color="#303030" font-style="Bold" label="Log In">
          <events>
            <buttonPress action="logIn"/>
          </events>
        </button>
      </cell>
    </row>
    <row height="1"/>
    <row/>
  </tableLayout>
</panel>

Open “secureLoginLogout_pkg” package again and create a procedure named “logOut” which will be fired when “Log out” hyperLink is clicked;

procedure logOut is
begin
  api_application.restart;
end;

Note that this procedure uses the api_application.restart API which reopens the current application and consequently changes the session id and terminate the old session.

Create a new action, enter “logOut” as the action name and “secureLoginLogout_pkg.logOut” as the procedure. Click “OK” to save your action. Add a click event to the “Log out” hyperLink triggering “logOut” action.

<panel font-size="14">
  <tableLayout cellSpacing="5">
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <hyperLink font-color="Blue" text-align="Right" label="Log out">
          <events>
            <click action="logOut"/>
          </events>
        </hyperLink>
      </cell>
    </row>
    <row>
      <cell hAlign="Full" vAlign="Full">
        <textLabel label="Welcome to the Tutorial Application. You may securely log out using the link above." text-align="Center"/>
      </cell>
    </row>
    <row>
      <cell hAlign="Full" vAlign="Center" childHeight="100">
        <button label="Dummy request">
          <events>
            <buttonPress/>
          </events>
        </button>
      </cell>
    </row>
  </tableLayout>
</panel>

Experimenting with the Secure Login/Logout Mechanism

Press “Run on Web” to run your application. You can easily track session id changes through the HTTP request headers. To achieve this in Chrome;

1. Press “F12” to open the “Developer Tools”
2. Select “Network” tab

“Network” tab selected

3. In the “secureLoginLogout” application, enter “test” as “Username” and “test” as “Password”. Press “Log In” button
4. In the “Developer Tools”, select “bdfservlet” and click “Headers” tab. Note the session id value displayed under the “Request Headers” section. This is the value of the session id just before the login (authentication).

The value of the session id just before the login

5. Press “Dummy Button” to create a dummy request, this is the first request since you are successfully logged in. In the “Developer Tools”, select the newly added “bdfservlet”. Note that since you have changed the session id using api_session.authenticate API when the user successfully logged in, the session id value of this request is different as expected.

Session id is changed when the user logged in

6. Press “Dummy Button” again. Note that the session id value is not changed and it’s exactly same with the step 5.
7. Click “Log out”, the application restarts. Press “Log In” while the “Username” and “Password” fields are empty. Note that since clicking the “Log out” hyperLink terminated the old session and reopened the aplication with a new session id, it’s value is different from the step 6.

Session id is changed when the application is restarted

  • Anatoly

    Just a silly question: as far as I know a lot of similar forms have a possibility to log in by “ENTER” shortkey. Here user should always click the “Log in” button. Is there any possibility to use shortkeys here?