08-27-2015 9:46 PM
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
08-31-2015 9:22 AM
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