Develop a Script for External Passcode Validation

By implementing scripts, you can use external passcode validation services. For example you can use RSA SecureID passcode to log on to applications.

Prerequisites

  • You have configured your policy configuration (application) to use the TOTPLoginModule with otp&pwd mode. For more information, see Configuring TOTPLoginModule and RBALoginModule.

  • You have administrator and user permissions.

  • You have configured a RADIUS destination in the Secure Login Administration Console.

    For more information, see Managing Destinations.

  • You have configured your server for authentication with RSA passcodes.

    You also have to configure the users who can use this authentication.

  • You have created the users in the AS Java user management engine (UME).

    For more information about how to add those users, see Creating a Technical User.

  • You have created an RSA_Users group in the UME and have assigned your users to the group.

    For more information, see Assigning Principals to Roles or Groups.

  • You have created a policy script named SAP of type Library in the Policy Script Administration Console at http(s)://<host>:<port>/ssoadmin/scripts with the following content:
    /**
    * This library defines the following namespaces: SAP, SAP.sample and SAP.util.
    * It has to be included before any other library provided by SAP.
    */
    var SAP = {
        sample : {},
        util : {}
    }
    
  • You have created a policy script named SAP_util_rsa of type Library in the Policy Script Administration Console at http(s)://<host>:<port>/ssoadmin/scripts with the following content:
    /**
    * This library provides an utility class for passcode validation against RSA SecurID server.
    * For additional information check the online documentation at http://help.sap.com/saphelp_nwsso20/helpdata/en/2c/c4781832aa4cd9bf5a253aa0ac1445/content.htm
    */
    SAP.util.rsa = {
    
        PasscodeValidator : {
    
            /**
             * Function to validate RSA passcode against a RSA server.
             * Supports RSA server failover via multiple RADIUS destinations
             *
             *
             * @param  {PolicyConfiguration} config  the configuration used for the current login. Different configuration options can be read and set
             * @param  {PolicyContext} context  policy context for the current login
             * @param  {PasscodeValidationLoginResult} result passcode validation result. End-user messages (warnings, errors, infos) are returned here along with the passcode validation status
             * @param  {String} username username used in the current login
             * @param  {String} passcode passcode to be validated
             * @param  {String[]} [destinations] array with the names of RADIUS destinations for failover support.
             *          When it is null or empty, the RADIUS destination name is taken from the login module option "rsa.login.module.option.RadiusDestination".
             *          When there is no such login module option the default RADIUS destination is used by "SecureLoginModule20RADIUS" login module.
             * @return {boolean} true when the given passcode is valid, false when is not valid or the validation is not possible
             */
            validate: function (config, context, result, username, passcode, destinations) {
                // The type of "logger" is LogAccessor
                var logger = context.getLogger();
                logger.traceDebug("Validating passcode against RSA server for user: " + username);
    
                // The type of "rsaContext" is RSAContext
               var rsaContext = context.getRsaContext();
    
                // RSA context is using the login module configured with configuration property "rsa.login.module" and default value "SecureLoginModule20RADIUS" for passcode validation.
                // "passcodeStatus" is of type String with values "VALID_PASSCODE", "INVALID_PASSCODE", "VALID_NEXT_PASSCODE_REQUIRED" or "RSA_SERVICE_UNAVAILABLE".
                var passcodeStatus;
    
                var processedPasscodeStatus;
    
                // no failover
                if (typeof destinations == "undefined" || destinations == null || destinations.length == 0) {
                    logger.traceInfo("No failover RADIUS destinations are specified.");
    
                    passcodeStatus = rsaContext.validatePasscode(username, passcode);
                    processedPasscodeStatus = processPasscodeStatus(passcodeStatus);
    
                    if (processedPasscodeStatus == null) {
                        logger.logError("The RADIUS destination was not available for passcode validation.");
                        result.setValidationFailureWithErrorMessage("Unable to validate RSA SecurID passcode. Contact your system administrator.");
                        return false;
                    }
                    return processedPasscodeStatus;
                }
    
                // failover
                logger.traceInfo("Using the following RADIUS destinations: " + destinations);
                var destinationsCount = destinations.length;
                for (var i = 0; i < destinationsCount; i++) {
                    if (!destinations[i]) {
                        continue;
                    }
    
                    rsaContext.setRADIUSDestination(destinations[i]);
    
                    passcodeStatus = rsaContext.validatePasscode(username, passcode);
                    processedPasscodeStatus = processPasscodeStatus(passcodeStatus);
                    if (processedPasscodeStatus == null) {
                        continue;
                    }
    
                    return processedPasscodeStatus;
                }
    
                // unsuccessful failover
                logger.logError("None of the configured RADIUS destinations were available for passcode validation.");
                result.setValidationFailureWithErrorMessage("Unable to validate RSA SecurID passcode. Contact your system administrator.");
                return false;
    
    
    
                function processPasscodeStatus(passcodeStatus) {
                    switch (passcodeStatus) {
                        // the configured RADIUS server is not available
                        case rsaContext.RSA_SERVICE_UNAVAILABLE: {
                            return null;
                        }
    
                        // Passcode validation passed successfully.
                        case rsaContext.VALID_PASSCODE:
                        {
                            logger.traceDebug("RSA SecurID passcode is accepted.");
                            result.setValidationSuccessful();
                            return true;
                        }
    
                        // Passcode is invalid. Issue a warning message.
                        case rsaContext.INVALID_PASSCODE:
                        {
                            logger.traceDebug("Invalid RSA SecurID passcode");
                            // A warning message is displayed on the logon page.
                            result.setValidationFailureWithWarningMessage("Wrong RSA SecurID passcode");
                            return false;
                        }
    
                        // Provide the next passcode. For example, when several wrong passcodes were entered on previous attempts.
                        case rsaContext.VALID_NEXT_PASSCODE_REQUIRED:
                        {
                            logger.traceDebug("RSA SecurID passcode is accepted. User should provide next one for confirmation");
                            // An information message is displayed on the logon page in case a second passcode is required.
                            result.setValidationFailureWithInfoMessage("RSA SecurID passcode accepted. Enter a second passcode to log on.");
                            return true;
                        }
    
                        default:
                        {
                            logger.traceDebug("Unknown RSA SecurID passcode status: " + passcodeStatus);
                            result.setValidationFailureWithErrorMessage("Unknown RSA SecurID passcode status. Contact your system administrator.");
                            return false;
                        }
                    }
                }
            }
        }
    };
    

Procedure

  1. Log on to the Policy Script Administration Console at http(s)://<host>:<port>/ssoadmin/scripts.
  2. Create the passcode validation script and save your configurations. If you have created more than one version of your policy script, make sure that the version you want to be executed during authentication is activated. For more information on how to create a policy script, see Working with Policy Scripts.
  3. Log on to the One-Time Password Administration UI at http(s)://<host>:<port>/ssoadmin/otp.
  4. Choose the Settings tab.
    Note

    To allow applications to use your policy script, make sure that the Policy checkbox under the Two-Factor Authentication section is selected.

  5. Choose the Policy Script... button under the Two-Factor Authentication section.
  6. From the dropdown list select the policy script that you have just created, and reload it. Only the activated versions of policy scripts are visible in the dropdown list.
  7. Save your configuration.
  8. Test the scenario as a user.