Add single signon authentication method (patch #1545366, patch #1541379, patch #1531302 and RFE #1031391).

This commit is contained in:
Michal Čihař
2006-08-24 12:38:29 +00:00
parent 22bb5059e2
commit 862bc35be7
6 changed files with 258 additions and 3 deletions

View File

@@ -5,6 +5,12 @@ phpMyAdmin - ChangeLog
$Id$
$Source$
2006-08-24 Michal Čihař <michal@cihar.com>
* Documentation.html, libraries/config.default.php,
libraries/auth/signon.auth.lib.php, scripts/signon.php,
scripts/setup.php: Add single signon authentication method (patch
#1545366, patch #1541379, patch #1531302 and RFE #1031391).
2006-08-22 Marc Delisle <lem9@users.sourceforge.net>
* scripts/setup.php: bug #1536112, better fix (in case of
register_globals enabled), thanks to Michal

View File

@@ -667,6 +667,16 @@ GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real
<li>'<abbr title="HyperText Transfer Protocol">HTTP</abbr>' authentication (was called 'advanced' in older versions)
(<tt>$auth_type&nbsp;=&nbsp;'<abbr title="HyperText Transfer Protocol">HTTP</abbr>'</tt>) as introduced in 1.3.0
allows you to log in as any valid MySQL user via HTTP-Auth.</li>
<li>'signon' authentication mode
(<tt>$auth_type&nbsp;=&nbsp;'signon'</tt>)
as introduced in 2.10.0 allows you to login from prepared PHP
session data. This is useful for implementing single signon
from another application. Sample way how to seed session is in
signon example: <code>scripts/signon.php</code>. You need to
configure <a href="#cfg_Servers_SignonSession"
class="configrule">session name</a> and <a
href="#cfg_Servers_SignonURL" class="configrule">signon
URL</a> to use this authentication method.
</ul>
Please see the <a href="#setup">install section</a> on &quot;Using authentication modes&quot;
@@ -1010,6 +1020,15 @@ ALTER TABLE `pma_column_comments`
<tt>xxx.xxx.xxx.xx[yyy-zzz]</tt> (partial
<abbr title="Internet Protocol">IP</abbr> address range)
</dd>
<dt><span id="cfg_Servers_SignonSession">$cfg['Servers'][$i]['SignonSession']</span> string</dt>
<dd>Name of session which will be used for signon authentication method.
</dd>
<dt><span id="cfg_Servers_SignonURL">$cfg['Servers'][$i]['SignonURL']</span> string</dt>
<dd>URL where user will be redirected for login for signon authentication method. Should be absolute including protocol.
</dd>
<dt><span id="cfg_Servers_LogoutURL">$cfg['Servers'][$i]['LogoutURL']</span> string</dt>
<dd>URL where user will be redirected after logout (doesn't affect config authentication method). Should be absolute including protocol.
</dd>
<dt id="cfg_ServerDefault">$cfg['ServerDefault'] integer</dt>
<dd>If you have more than one server configured, you can set

View File

@@ -0,0 +1,166 @@
<?php
/* $Id$ */
// vim: expandtab sw=4 ts=4 sts=4:
// +--------------------------------------------------------------------------+
// | Set of functions used to run single signon authentication. |
// +--------------------------------------------------------------------------+
/**
* Displays authentication form
*
* @global string the font face to use in case of failure
* @global string the default font size to use in case of failure
* @global string the big font size to use in case of failure
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth() {
if (empty($GLOBALS['cfg']['Server']['SignonURL'])) {
PMA_sendHeaderLocation('error.php?error=' . urlencode('You must set SignonURL!'));
} elseif (!empty($_REQUEST['old_usr']) && !empty($GLOBALS['cfg']['Server']['LogoutURL'])) {
/* Perform logout to custom URL */
PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
} else {
PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['SignonURL']);
}
exit();
} // end of the 'PMA_auth()' function
/**
* Gets advanced authentication settings
*
* @global string the username if register_globals is on
* @global string the password if register_globals is on
* @global array the array of server variables if register_globals is
* off
* @global array the array of environment variables if register_globals
* is off
* @global string the username for the ? server
* @global string the password for the ? server
* @global string the username for the WebSite Professional server
* @global string the password for the WebSite Professional server
* @global string the username of the user who logs out
*
* @return boolean whether we get authentication settings or not
*
* @access public
*/
function PMA_auth_check()
{
global $PHP_AUTH_USER, $PHP_AUTH_PW;
/* Session name */
$session_name = $GLOBALS['cfg']['Server']['SignonSession'];
/* Are we requested to do logout? */
$do_logout = !empty($_REQUEST['old_usr']);
/* Does session exist? */
if (isset($_COOKIE[$session_name])) {
/* End current session */
$old_session = session_name();
$old_id = session_id();
session_write_close();
/* Load single signon session */
session_name($session_name);
session_id($_COOKIE[$session_name]);
session_start();
/* Grab credentials if they exist */
if (isset($_SESSION['PMA_single_signon_user'])) {
if ($do_logout) {
$PHP_AUTH_USER = '';
} else {
$PHP_AUTH_USER = $_SESSION['PMA_single_signon_user'];
}
}
if (isset($_SESSION['PMA_single_signon_password'])) {
if ($do_logout) {
$PHP_AUTH_PW = '';
} else {
$PHP_AUTH_PW = $_SESSION['PMA_single_signon_password'];
}
}
/* Also get token as it is needed to access subpages */
if (isset($_SESSION['PMA_single_signon_token'])) {
/* No need to care about token on logout */
$pma_token = $_SESSION['PMA_single_signon_token'];
}
/* End signle signon session */
session_write_close();
/* Restart phpMyAdmin session */
session_name($old_session);
if (!empty($old_id)) {
session_id($old_id);
}
session_start();
/* Restore our token */
if (!empty($pma_token)) {
$_SESSION['PMA_token'] = $pma_token;
}
}
// Returns whether we get authentication settings or not
if (empty($PHP_AUTH_USER)) {
return false;
} else {
return true;
}
} // end of the 'PMA_auth_check()' function
/**
* Set the user and password after last checkings if required
*
* @global array the valid servers settings
* @global integer the id of the current server
* @global array the current server settings
* @global string the current username
* @global string the current password
*
* @return boolean always true
*
* @access public
*/
function PMA_auth_set_user()
{
global $cfg;
global $PHP_AUTH_USER, $PHP_AUTH_PW;
$cfg['Server']['user'] = $PHP_AUTH_USER;
$cfg['Server']['password'] = $PHP_AUTH_PW;
return true;
} // end of the 'PMA_auth_set_user()' function
/**
* User is not allowed to login to MySQL -> authentication failed
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth_fails()
{
$error = PMA_DBI_getError();
if ($error && $GLOBALS['errno'] != 1045) {
PMA_sendHeaderLocation('error.php?error=' . urlencode($error));
exit;
} else {
PMA_auth();
return true;
}
} // end of the 'PMA_auth_fails()' function
?>

View File

@@ -68,10 +68,13 @@ $cfg['Servers'][$i]['controlpass'] = ''; // access to the "mysql/user
// The controluser is also
// used for all relational
// features (pmadb)
$cfg['Servers'][$i]['auth_type'] = 'config'; // Authentication method (config, http or cookie based)?
$cfg['Servers'][$i]['auth_type'] = 'config'; // Authentication method (config, http, signon or cookie based)?
$cfg['Servers'][$i]['user'] = 'root'; // MySQL user
$cfg['Servers'][$i]['password'] = ''; // MySQL password (only needed
// with 'config' auth_type)
$cfg['Servers'][$i]['SignonSession'] = ''; // Session to use for 'signon' auth method
$cfg['Servers'][$i]['SignonURL'] = ''; // URL where to redirect user to login for 'signon' auth method
$cfg['Servers'][$i]['LogoutURL'] = ''; // URL where to redirect user after logout
$cfg['Servers'][$i]['nopassword'] = FALSE; // Whether to try to connect without password
$cfg['Servers'][$i]['only_db'] = ''; // If set to a db-name, only
// this db is displayed in left frame

View File

@@ -938,7 +938,7 @@ function show_server_form($defaults = array(), $number = FALSE) {
array('Connection type', 'connect_type', 'How to connect to server, keep tcp if unsure', array('tcp', 'socket')),
array('PHP extension to use', 'extension', 'What PHP extension to use, use mysqli if supported', array('mysql', 'mysqli')),
array('Compress connection', 'compress', 'Whether to compress connection to MySQL server', FALSE),
array('Authentication type', 'auth_type', 'Authentication method to use', array('cookie', 'http', 'config')),
array('Authentication type', 'auth_type', 'Authentication method to use', array('cookie', 'http', 'config', 'signon')),
array('User for config auth', 'user', 'Leave empty if not using config auth'),
array('Password for config auth', 'password', 'Leave empty if not using config auth', 'password'),
array('Only database to show', 'only_db', 'Limit listing of databases in left frame to this one'),
@@ -946,6 +946,9 @@ function show_server_form($defaults = array(), $number = FALSE) {
array('phpMyAdmin control user', 'controluser', 'User which phpMyAdmin can use for various actions'),
array('phpMyAdmin control user password', 'controlpass', 'Password for user which phpMyAdmin can use for various actions', 'password'),
array('phpMyAdmin database for advanced features', 'pmadb', 'phpMyAdmin will allow much more when you enable this. Table names are filled in automatically.'),
array('Session name for signon auth', 'SignonSession', 'Leave empty if not using signon auth'),
array('Login URL for signon auth', 'SignonURL', 'Leave empty if not using signon auth'),
array('Logout URL', 'LogoutURL', 'Where to redirect user after logout'),
),
'Configure server',
($number === FALSE) ? 'Enter new server connection parameters.' : 'Editing server ' . get_server_name($defaults, $number),
@@ -1276,7 +1279,7 @@ switch ($action) {
case 'addserver_real':
if (isset($_POST['submit_save'])) {
$new_server = grab_values('host;extension;port;socket;connect_type;compress:bool;controluser;controlpass;auth_type;user;password;only_db;verbose;pmadb;bookmarktable:serialized;relation:serialized;table_info:serialized;table_coords:serialized;pdf_pages:serialized;column_info:serialized;history:serialized;AllowDeny:serialized');
$new_server = grab_values('host;extension;port;socket;connect_type;compress:bool;controluser;controlpass;auth_type;user;password;only_db;verbose;pmadb;bookmarktable:serialized;relation:serialized;table_info:serialized;table_coords:serialized;pdf_pages:serialized;column_info:serialized;history:serialized;AllowDeny:serialized;SignonSession;SignonURL;LogoutURL');
$err = FALSE;
if (empty($new_server['host'])) {
message('error', 'Empty hostname!');
@@ -1286,6 +1289,14 @@ switch ($action) {
message('error', 'Empty username while using config authentication method!');
$err = TRUE;
}
if ($new_server['auth_type'] == 'signon' && empty($new_server['SignonSession'])) {
message('error', 'Empty signon session name while using signon authentication method!');
$err = TRUE;
}
if ($new_server['auth_type'] == 'signon' && empty($new_server['SignonURL'])) {
message('error', 'Empty signon URL while using signon authentication method!');
$err = TRUE;
}
if ( isset($new_server['pmadb']) && strlen($new_server['pmadb'])) {
// Just use defaults, should be okay for most users
$pmadb = array();

50
scripts/signon.php Normal file
View File

@@ -0,0 +1,50 @@
<?php
/* $Id$ */
// vim: expandtab sw=4 ts=4 sts=4:
// Single signon for phpMyAdmin
//
// This is just example how to use signle signon with phpMyAdmin, it is
// not intented to be perfect code and look, only shows how you can
// integrate this functionality in your application.
/* Was data posted? */
if (isset($_POST['user'])) {
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', 0);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
session_start();
/* Store there credentials */
$_SESSION['PMA_single_signon_user'] = $_POST['user'];
$_SESSION['PMA_single_signon_password'] = $_POST['password'];
$id = session_id();
/* Close that session */
session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {
/* Show simple form */
header('Content-Type: text/html; charset=utf-8');
echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
<title>phpMyAdmin signle signon example</title>
<html>
<body>
<form action="signon.php" method="post">
Username: <input type="text" name="user" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" />
</form>
</body>
</html>
<?php
}
?>