Develop a Script for Context-Based Authorizations

Prerequisites

Procedure

  1. Log on to the Policy Script Administration Console at http(s)://<host>:<port>/ssoadmin/scripts.
  2. Create a context-based 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 is activated. For more information on how to create a policy script, see Working with Policy Scripts.

    This script accomplishes the following:

    • Controls first factor logon according to the IP range.

    • Decides on the second factor logon according to the first factor authentication method.

    • Does not require second factor for users that are not administrators.

    • Allows administrators to log on with full access permissions by providing a second factor.

      For the second factor logon, the application can send the password via SMS or email.

    var EMAIL = {
      send : function (recipient, subject, message, logger) {
        try {
          var server = com.sap.security.api.UMFactory.getProperties().getDynamic("ume.notification.mail_host", "mail");
          var sender = com.sap.security.api.UMFactory.getProperties().getDynamic("ume.notification.system_email", "donotreply@acme.com");
          var props = new java.util.Properties();
          props.put("mail.smtp.host", server);
          var session = javax.mail.Session.getDefaultInstance(props, null);
          session.setDebug(false);
          var msg = new javax.mail.internet.MimeMessage(session);
          var addressFrom = new javax.mail.internet.InternetAddress(sender);
          msg.setFrom(addressFrom);
          var addressTo = java.lang.reflect.Array.newInstance(javax.mail.internet.InternetAddress, 1);
          addressTo[0] = new javax.mail.internet.InternetAddress(recipient);
          msg.setRecipients(javax.mail.Message.RecipientType.TO, addressTo);
          msg.setSubject(subject, "utf-8");
          msg.setContent(message, "text/plain; charset=utf-8");
          javax.mail.Transport.send(msg);    
          return true;
        } catch (err) {
          if (logger) {
            logger.traceError("Passcode cannot be sent via email.", err);
          }
          return false;
        }
      }
    };
    
    
    function onInitialize(config, context) {
      var httpClientContext = context.getHttpClientContext();
      if (httpClientContext.getClientIP().startsWith("10.11.12")) {
        config.setProperty("tfa.first.factor.login.module", "ClientCertLoginModule, SPNegoLoginModule, BasicPasswordLoginModule");
      } else {
        config.setProperty("tfa.first.factor.login.module", "ClientCertLoginModule, BasicPasswordLoginModule");
      }
    }
    
    function onFirstStageLogin(config, context, result) {
      var loginInfo = context.getLoginInfo();
      var authnMethod = loginInfo.getAuthenticationMethod();
      if (authnMethod == "certificate" || authnMethod == "spnego") {
        result.doNotRequireSecondFactor();
         return;
      }
      var user = loginInfo.getUser();
      if (user.isMemberOfGroup("GRUP.PRIVATE_DATASOURCE.un:Administrators", true) ||
          user.isMemberOfRole("ROLE.UME_ROLE_PERSISTENCE.un:Administrator", true)) {
        result.setOptionalSecondFactor(
         "Select your access permissions to log on:",
         "Limited permissions",
         "Administrator permissions",
         result.DEFAULT_SELECTION_LIMITED_ACCESS);
      } else {
        result.doNotRequireSecondFactor();
      }
    }
    
    function onLimitedAccessSelected(config, context, result) {
      result.setAuthorizationScopes([], result.GRANT_ROLES_WITHOUT_SCOPES);
    }
    
    function onFullAccessSelected(config, context, result) {
      var logger = context.getLogger();
      var loginInfo = context.getLoginInfo();
      var user = loginInfo.getUser();
      var totpInfo = loginInfo.getTOTPInfo();
      if (totpInfo.getStatus() == totpInfo.DISABLED || totpInfo.getStatus() == totpInfo.EXPIRED) {
        if (user.getCellPhone()) {
          config.setProperty("tfa.passcode.via.sms", "yes");
          var passcode = result.setRandomPasscode(10, 15, 5, "Passcode sent via SMS. Please enter the passcode to log on.");
        } else if (user.getEmail()) {
          config.setProperty("tfa.passcode.via.sms", "no");
          var passcode = result.setRandomPasscode(10, 15, 5, "Passcode sent via email. Please enter the passcode to log on.");
          EMAIL.send(user.getEmail(), "Access to CompanyA Inc. Portal", "Hello " + user.getFirstName() + " " + user.getLastName() + ",\n\nTo log on, please enter the following passcode: " + passcode + ".\n\nYour Portal IT Team", logger);
        } else {
          result.abortLogin('Passcode cannot be sent via SMS or email. Please contact system administrator.');
        }
      }
    }
    
    function onSecondStageLogin(config, context, result) {
      result.setAuthorizationScopes(["FULL_ACCESS"], result.GRANT_ROLES_WITHOUT_SCOPES);
    }
    
  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.