Child pages
  • Upgrade existing implementations to Servoy 5.2's Enhanced Security

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

An Authenticator solution is called from the a Login solution using the function:

Code Block

security.authenticate(authenticatorSolutionName, globalMethodName, argumentsArray);

...

The Login solution can however request data required for the login process through an Authenticator solution using the function:

Code Block

security.authenticate(authenticatorSolutionName, globalMethodName, argumentsArray);

...

This example shows how to convert a solution that uses its own logic to validate user credentials (for instance checking with an LDAP server). The login form prompts the user for a username, password and department. The departments are retrieved from a value list that contains all records departments table and are shown in a dropdown.

Code Block

var userName = ''; //Will be specified by user

var departmentName = ''; //Will be specified by user

function login(event) {
  var authenticated = ... //  contact LDAP server
  if (authenticated) {
    var ok =  security.login(userName, userName, [departmentName]) // Assume a group for each department
    application.output('User ' + userName + ' authenticated: ' + ok, LOGGINGLEVEL.DEBUG);
  } else {
    application.output('User 'userName' could not be authenticated', LOGGINGLEVEL.DEBUG);
  }
}

New solution
A new solution 'Login' (solutionType Login) is created, the login form from the original solution is moved to the Login solution, the form has no datasource attached (datasource is set to -none-). A custom value list is created in the new solution called departments (no entries, will be filled in the login form)
The onShow event of the form retrieves required data via the authenticator.

Code Block

function onShow(firstShow, event) {
  if (firstShow) {
    var departments = security.authenticate('Authenticator','getDepartments');
    application.setValueListItems('departments', departments)
  }
}

The login method attached to the login button in the login solution is altered to also call the authenticator:

Code Block

function login(event) {
  security.authenticate('Authenticator', 'login', [userName, passWord, departmentName]);
}

Another solution 'Authenticator' (solutionType Authenticator) is created. The departments value list from the original solution is copied to the Authenticator solution.
The solution will not have any forms, only global methods for fetching of the required data and the actual authentication logic.

Code Block

function getDepartments() {  
  return application.getValueListItems('departments')
}

function login(user, password, department) {
  if (!(user && password && department)) {
    application.output('Unexpected credentials received', LOGGINGLEVEL.DEBUG);
    return false;
  }
  var authenticated = ... // contact LDAP server
  if (authenticated) {
    var ok = security.login(object.user, object.user, object.dep) // Assume a group for each department
    application.output('User ' + user + ' authenticated: ' + ok, LOGGINGLEVEL.DEBUG);
    return ok;
  }
  application.output('User ' + user + ' could not be authenticated', LOGGINGLEVEL.DEBUG);
  return false;
}

...

When the authentication code is something along the following lines:

Code Block

function login(userName, password) {
   var userUID = security.getUserUID(userName);
   if (security.checkPassword(userUID, password)) {
      return security.login(userName, userUID, security.getUserGroups(userUID))
   } 
   return false;
}

The shortcut that can be taken in the use of null Authenticator in the Login solution:

Code Block

security.authenticate(null, null, [userName, password]);

...

The security.authenticate(...) function can be utilized as long as there is no logged in user.

Examples

From the Servoy Example SVN a simple demo solution demonstrating the Enhanced Security mechanism can be checked out:

...