Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Can't send One Time Password via SMS-Gateway

Former Member
0 Kudos

Hello,

we are about to release some apps via the FLP were the employee should logon by using two-

factor authentication (PWD&OTP) over an identity provider (as java).

Current State:

The above scenario is technically working. The user can authenticate

with the OTP generated on an mobile device, but that's not our

preferred way of delivering the OTP. It should be SMS.

SMS-Problem:

For sending SMS via HTTPS we stored an SSL certificate of the sms-

gateway provider in the as java identity provider. Additionally we

created a new HTTP Destination to the SMS-Gateway

location by referring to the SSL certificate and delivering basic

authentication. This all authentication and certificate is working,

if we provide the required URL-Parameters right in the field of the

destination URL and use the "Ping" function.

Here is the problem. The SMS-gateway needs some defined URL

parameters to work. They are "key=", "message=" and "to=". Wether in

the NWA>Destination UI nor in the OTPADMIN UI it is possible to map

the generated Message with passcode to the right URL Parameter which

is required by the SMS-gateway.

The HTTP API Documentation for the SMS-Gateway you find here

If this is a specific problem with this special provider, maybe you

can provide another one, which does not have this special

requirements. Maybe there is a workaround possible with some development on the java side.


Best regards,

Julian Branahl

1 REPLY 1

former_member182254
Active Participant
0 Kudos

Hello Julian,

I have already replied in the support ticket that you have opened but I will paste the information also here to share it with the community.

The functionality for sending SMS messages works out-of-the box only with SMS gateway from SAP. In order to use a 3rd party SMS gateway you would need a policy script which implements the specific API of the 3rd party gateway. Attached are sample scripts which should help to implement your scenario. Here are the necessary steps to enable it:

1.http://help.sap.com/saphelp_nwsso20/helpdata/en/c5/9bd64e06b44edea169bf4866a09bf6/content.htm

- Create access policy "destination" with type "Library" using the attached "destination.txt" file

- Create access policy "sms" with type "Library" using the attached "sms.txt" file

2.http://help.sap.com/saphelp_nwsso20/helpdata/en/3c/d788a749ec427cafea6aa40d596843/content.htm

- Set the global OTP policy using the attached "policy.txt" file.

3.Set the following settings in OTP Admin UI (/otpadmin)

- Unselect option "Send passcode by SMS" - that's not a typo, if this option is selected it will try to send the SMS using the standard functionality for SAP SMS Gateway, that's why this option should be UNselected

- Select option "Policy" in order to enable the execution of the script set at step 2

- Select valid "Destination Name" in section "SMS Gateway"

Regards,

Dimitar

Scripts:

// Begin of destination.txt

function HttpDestination(name, logger) {

  this.name = name;

  this.logger = logger;

  this.destination = com.sap.security.core.server.destinations.api.DestinationServiceLocator.getInstance().getDestination("HTTP", name);

}

HttpDestination.prototype.getUrlConnection = function (params) {

  var url = this.destination.getUrl();

  var urlConnection;

  if (params) {

    var newUrl = url.contains("?") ? url+"&"+params : url+"?"+params;

    this.destination.setUrl(newUrl);

    urlConnection = this.destination.getURLConnection();

    this.destination.setUrl(url);

  } else {

    urlConnection = this.destination.getURLConnection();

  }

  return urlConnection;

}

// End of destination.txt

// Begin of sms.txt

function SmsGateway (httpDestination, logger) {

  this.httpDestination = httpDestination;

  this.logger = logger;

}

SmsGateway.prototype.send = function (to, message) {

  var params = "to=" + java.net.URLEncoder.encode(to, "UTF-8") + "&message=" + java.net.URLEncoder.encode(message, "UTF-8");

  var urlConnection = this.httpDestination.getUrlConnection(params);

  var is;

  var responseCode;

  try {

    urlConnection.connect();

    is = urlConnection.getInputStream();

    var reader = new java.io.BufferedReader(new java.io.InputStreamReader(is));

    responseCode = reader.readLine();

  } finally {

    if (is) {

      is.close();

    }

  }

  return responseCode;

}

// End of sms.txt


// Begin of policy.txt

#include "destination";

#include "sms";

function onFirstStageLogin(config, context, result) {

  var logger = context.getLogger();

  var user = context.getLoginInfo().getUser();

  var cellPhoneNumber = user.getCellPhone();

  var smsDestinationName = config.getProperty("sms.destination");

  var smsMessageText = config.getProperty("sms.message.text");

  if (cellPhoneNumber && smsDestinationName && smsMessageText) {

    var httpDestination = new HttpDestination(smsDestinationName, logger);

    var smsGateway = new SmsGateway(httpDestination, logger);

    var passcode = result.setRandomPasscode(config.getProperty("sms.token.length"), config.getProperty("sms.token.validity"), config.getProperty("sms.max.failed.attempts"), "Passcode sent via SMS; enter the passcode to logon");

    var message = smsMessageText.replace("[passcode]", passcode);

    var responseCode = smsGateway.send(user.getCellPhone(), message);

    if (responseCode != 100) {

      logger.traceWarning("SMS gateway response code: " + responseCode);

      result.abortLogin('Passcode cannot be sent via SMS; contact the system administrator'); 

    }

  } else {

    result.abortLogin('Passcode cannot be sent via SMS; contact the system administrator'); 

  }

}

// End of policy.txt