Introduction
In this blog I will try to explain how can SAP Single Sign On be integrated in a PHP application.
At first we need to see what is Single Sign On at all and why do we need that. One business user works with a set of enterprise applications, which generally have different login data. Since it would be very inefficient to enter so many times user ID and password, a Single Sign On technology can be applied in terms of entering a single password and all other systems becomming accessible without further login.Now let us see what logon options with SAP systems are available:
- User ID and password
- Secure Network Communications (SNC)
- SAP logon tickets
- SSL and X.509 client certificates
- Pluggable Authentication Services (PAS)
- Security Assertion Markup Language (SAML)
- Java Authentication and Authorization Service (JAAS)
Where the authentication data is stored depends on the (PHP) application. In this blog I will consider SAP logon tickets as authentication option.
Scenario and Application Structure
The following scenario is used to illustrate the concepts: Check Material Availability. The application displays a form with input fields for a specific material number and type. When the form is submitted, a check is performed and the number of available materials is returned. This service is implemented as an ABAP service (through RFC) and as a web service. Single Sign On with SAP logon tickets can be used to authenticate for both of them.
If there is no logon ticket present, the PHP application asks the user for user ID and password. After this it authenticates him to the SAP system and receives a logon ticket. This logon ticket is after that saved to a cookie, called MYSAPSSO2
(this is the standard name, used by SAP Enterprise Portal). On each other start of the application this cookie is read and the login form is skipped. On log out the cookie is deleted. In a more sofisticated application log out should be performed also to the SAP system.</p>
Single Sign On with RFC
For this sample the SAPRFC connector for PHP from Eduard Koucký is used.The RFC service has the following parameters:
- Input: plant (string), material (string), unit (string) - what material we address and in which units is the availability to be returned.
- Output: q_av_plt (string) - amount available.
The application consists of the following files:
- login.php - the login form and code to optain SAP logon ticket.
- logout.php - cleans the MYSAPSSO2 cookie in browser.
- index.php - the material check form.
- material_check.php - calls the material check RFC service.
- login_routines.inc.php - check for login errors.
- cookie.inc.php - cookie handling functions.
- common.inc.php - contains the RFC calls.
The contents of the source files follows:
login.php
In this example file the most important thing to note is that with opening the SAPRFC connection we set the GETSSO2 parameter to 1, which instructs the R/3 system to create an SAP logon ticket. The created ticket is then retrieved with saprfc_get_ticket().
Material Check Demo Logon Page
RFC and Single Sign On with PHP
This demo requires, that cookies in Your browser are enabled. function login_to_SAP($login_name, $password) { $conn = array ( "ASHOST" => "mysapsystem", "SYSNR" => "09", "CLIENT" => "004", "USER" => $login_name, "PASSWD" => $password, "GETSSO2" => "1", "GWHOST" =>"mysapsystem", "R3NAME" =>"MSS", "LANG" =>"EN"); // Initialize SAPRFC library. $rfc = saprfc_open ($conn); if (! $rfc ) { saprfc_close($rfc); return "ER: reason=" . LOGIN_REASON_FAILED . "&desc=" . saprfc_error(); } $logon_ticket = saprfc_get_ticket($rfc); if ($logon_ticket==null) return "ER: reason=" . LOGIN_REASON_CANNOT_GET_TICKET . "&desc=" . saprfc_error(); // Close SAPRFC library. saprfc_close($rfc); return "OK: " . $logon_ticket;}?>
logout.php
Logout
Logout successful.
Log In
</body>
</html></textarea>
index.php
Check Material Availability
RFC and Single Sign On with PHP
echo "The material you requested is "; if ($avail>0) { echo "available. Amount = " . $avail . ""; } else { echo "not available."; } ?>
Back to form
Log Out
material_check.php
Check Material Availability
RFC and Single Sign On with PHP
echo "The material you requested is "; if ($avail>0) { echo "available. Amount = " . $avail . ""; } else { echo "not available."; } ?>
View Script
Back to form
Back to menu
Log Out
login_routines.inc.php
"Cannot get SAP logon ticket. Server error.",
);
/**
*
*
- Check if user is authorized. If not - redirect to the login page.
*/
function check_login() {
$ticket = get_cookie_value(SSOCOOKIE);
if (null==$ticket) {
if (array_key_exists('attempt', $_GET))
redirect("login.php?reason=" . LOGIN_REASON_PASSWORD_NOT_SET);
else
redirect("login.php");
}
}
function logout() {
// Warning!!! In a real implementation only deleting the cookie is not enough.
// We have also to be sure, that user has logged out from R/3.
if (!delete_cookie(SSOCOOKIE)) die("Cannot log out. Cookies not available.");
}
function get_reason($login_reasons) {
$app = " ";
if (!array_key_exists('reason', $_GET)) return $login_reasons[LOGIN_REASON_DEFAULT] . $app;
if (array_key_exists($_GET['reason'], $login_reasons)) {
return "" . $login_reasons[$_GET['reason']] . $app . ""; } else { return "Error code: " . $_GET['reason'] . ". Please, contact your SAP advisor for further details." . $app . ""; }}?>
cookie.inc.php
<?php
// Constants.
define("SSOCOOKIE", "MYSAPSSO2");
/**
*
- function get_cookie_value($cookie_name);
*
- Displays a cookie from user's browser.
*
- Provided parameter is cookie name.
*
- Return value is the cookie value, or null if not found.
*/
function get_cookie_value($cookie_name) {
if (null==$_COOKIE) return null;
if (array_key_exists($cookie_name, $_COOKIE)) {
$val = $_COOKIE[$cookie_name];
return $val;
}
return null;
}
/**
*
- function set_cookie_value($cookie_name, $cookie_value, $days_valid);
*
- Saves a cookie in user's browser.
*
- Provided parameters are cookie name and value and number of days,
- the cookie remains valid.
*
- Return values are true on success and false on failure.
- Failure normally means, that user has disabled cookies in the browser.
*/
function set_cookie_value($cookie_name, $cookie_value, $days_valid) {
$expires = time() + ($days_valid * 24 * 60 * 60);
// x days; 24 hours; 60 mins; 60 secs
if (setcookie($cookie_name, $cookie_value, $expires)) {
return true;
}
else {
return false;
}
}
/**
*
- function delete_cookie($cookie_name);
*
- Delete a cookie in user's browser.
*
- Provided parameters are cookie name and value and number of days,
- the cookie remains valid.
*
- Return values are true on success and false on failure.
- Failure normally means, that user has disabled cookies in the browser.
*/
function delete_cookie($cookie_name) {
return set_cookie_value($cookie_name, null, 0);
}
function redirect($location) {
Header("Location: " . $location);
}
?></textarea>
common.inc.php
Single Sign On with Web Services
In the web service sample the internal web service extension for PHP 5 is used.
The web service has the same parameters like the RFC one:
- Input: plant (string), material (string), unit (string) - what material we address and in which units is the availability to be returned.
- Output: availability (string) - amount available.
Besides that it is assumed that the web service is configured with basic HTTP security and with option to accept/issue SAP logon ticket. For more information how to do that please follow this link .
Like the RFC one, this application also consists of the following files:
- login.php - the login form and code to optain SAP logon ticket.
- logout.php - cleans the MYSAPSSO2 cookie in browser.
- index.php - the material check form.
- material_check.php - calls the material check RFC service.
- login_routines.inc.php - check for login errors.
- cookie.inc.php - cookie handling functions.
- common.inc.php - contains the RFC calls.
The files are very similar, but the only difference is that the RFC call functions are changed with web service call ones.
login.php
Material Check Demo Logon Page
Web Services and Single Sign On with PHP
logout.php
Logout
Logout successful.
Log In
</body>
</html></textarea>
index.php
Check Material Availability
Web Services and Single Sign On with PHP
You have been logged on via Single Sign On. Please, enter the check criteria:
Back
Log Out
material_check.php
Check Material Availability
RFC and Single Sign On with PHP
echo "The material you requested is "; if ($avail>0) { echo "available. Amount = " . $avail . ""; } else { echo "not available."; } ?>
View Script
Back to form
Log Out
login_routines.inc.php
"Cannot get SAP logon ticket. Server error.",
);
/**
*
*
- Check if user is authorized. If not - redirect to the login page.
*/
function check_login() {
$ticket = get_cookie_value(SSOCOOKIE);
if (null==$ticket) {
if (array_key_exists('attempt', $_GET))
redirect("login.php?reason=" . LOGIN_REASON_PASSWORD_NOT_SET);
else
redirect("login.php");
}
}
function logout() {
// Warning!!! In a real implementation only deleting the cookie is not enough.
// We have also to be sure, that user has logged out from R/3.
if (!delete_cookie(SSOCOOKIE)) die("Cannot log out. Cookies not available.");
}
function get_reason($login_reasons) {
$app = " ";
if (!array_key_exists('reason', $_GET)) return $login_reasons[LOGIN_REASON_DEFAULT] . $app;
if (array_key_exists($_GET['reason'], $login_reasons)) {
return "" . $login_reasons[$_GET['reason']] . $app . ""; } else { return "Error code: " . $_GET['reason'] . ". Please, contact your SAP advisor for further details." . $app . ""; }}?>
cookie.inc.php
<?php
// Constants.
define("SSOCOOKIE", "MYSAPSSO2");
define("HEADER_NAME", "Set-Cookie:");
/**
*
- function get_cookie_value($cookie_name);
*
- Displays a cookie from user's browser.
*
- Provided parameter is cookie name.
*
- Return value is the cookie value, or null if not found.
*/
function get_cookie_value($cookie_name) {
if (null==$_COOKIE) return null;
if (array_key_exists($cookie_name, $_COOKIE)) {
$val = $_COOKIE[$cookie_name];
return $val;
}
return null;
}
/**
*
- function set_cookie_value($cookie_name, $cookie_value, $days_valid);
*
- Saves a cookie in user's browser.
*
- Provided parameters are cookie name and value and number of days,
- the cookie remains valid.
*
- Return values are true on success and false on failure.
- Failure normally means, that user has disabled cookies in the browser.
*/
function set_cookie_value($cookie_name, $cookie_value, $days_valid) {
$expires = time() + ($days_valid * 24 * 60 * 60);
// x days; 24 hours; 60 mins; 60 secs
if (setcookie($cookie_name, $cookie_value, $expires)) {
return true;
}
else {
return false;
}
}
/**
*
- function delete_cookie($cookie_name);
*
- Delete a cookie in user's browser.
*
- Provided parameters are cookie name and value and number of days,
- the cookie remains valid.
*
- Return values are true on success and false on failure.
- Failure normally means, that user has disabled cookies in the browser.
*/
function delete_cookie($cookie_name) {
return set_cookie_value($cookie_name, null, 0);
}
function redirect($location) {
Header("Location: " . $location);
}
?></textarea>
common.inc.php