phpMyAdmin 跨多服务器单点登录最佳实践

phpMyAdmin 跨多服务器单点登录最佳实践

我经营一家小型网络开发公司,我们运行多台生产服务器,每台服务器都有自己的 MySQL 数据库服务器。我正在尝试找出将这些单独的 MySQL 实例授予我的团队的最佳方式。

我已经在一台服务器上设置了 phpMyAdmin,并且设置不同的 DB 主机表面上非常简单,使用基于 cookie 的身份验证即可登录到所有主机。

这种方法的问题在于,我们需要在每台服务器上维护每个团队成员的用户帐户。这会给密码管理以及员工的入职和离职带来麻烦。

我想要做的是使用 phpMyAdmin 提供的登录身份验证,这样我们只需维护一组用户权限。感觉我们应该能够使用现有 PHP 应用程序的框架来做到这一点,我一直在研究示例 signon.php 和 signon-script.php 文件,试图让它工作。

我到目前为止都失败了。所以我的问题是:

  1. 有谁有设置这项功能的经验并能告诉我最好的设置方法,或者提供一些比 phpMyAdmin 提供的更好的文档吗?
  2. 是否有人知道一个好的开源项目,可以以一个小型的独立 PHP 应用程序提供此功能?

我也考虑过使用基于配置的身份验证,然后将 Apache 的 HTTP Basic Auth 放在其上,但这样做的缺点是有据可查的。欢迎提出任何建议。

答案1

所以我基本解决了我的问题。还有一个错误,你必须注销并重新登录才能切换服务器。但除此之外,它还可以工作,使用第一个命名服务器作为登录凭据(从安全角度来看,这实际上可能不是最好的方法)。无论如何,这里有一些代码,它们位于 signon/index.php 的新文件中:

<?php

include '../config.inc.php';

$session_name = $cfg['Servers'][1]['SignonSession'];
session_set_cookie_params(0, '/', '', false, true);
session_name($session_name);

@session_start();

if(@$_SESSION['PMA_single_signon_user'] && !@$_GET['logout']) {
    header('Location: ../index.php');
    exit;
}
else {
    $_SESSION = [];
}

$error = "";

if($_POST) {
    
    //try to log in to the primary server with the credentials supplied
    $mysqli = mysqli_connect($cfg['Servers'][1]['host'], $_POST['username'], $_POST['password']);
    
    if($mysqli) {
        //find the host
        foreach($cfg['Servers'] as $svr) {
            if(@$svr['host'] == $_POST['host']) break;
        }
        
        /* Store the credentials */
        $_SESSION['PMA_single_signon_user'] = $svr['signon_user'];
        $_SESSION['PMA_single_signon_password'] = $svr['signon_password'];
        $_SESSION['PMA_single_signon_host'] = $_POST['host'];
        $_SESSION['PMA_single_signon_port'] = '';
        /* Update another field of server configuration */
        $_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => $svr['verbose'] ?? $svr['host'], 'host' => $svr['host']];
        $_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(random_int(0, mt_getrandmax())), true));
        $id = session_id();
        /* Close that session */
        @session_write_close();
        
        /* Redirect to phpMyAdmin (should use absolute URL here!) */
        header('Location: ../index.php');
        exit;
    }
    else {
        $error = "<p>The supplied credentials are not valid for the primary server</p>";
    }
}
print <<<abc
        <form method="post">
            {$error}
            <table>
                <tr>
                    <th>Username: </th>
                    <td><input name="username" type="text"></td>
                </tr>
                <tr>
                    <th>Password: </th>
                    <td><input name="password" type="password"></td>
                </tr>
                <tr>
                    <th>Host: </th>
                    <td><select name="host">
abc;
    foreach($cfg['Servers'] as $i => $c) {
        print "<option value=\"{$c['host']}\">" . (@$c['verbose'] ?? $c['host']) . "</option>\n";
    }
print <<<abc
                    </select></td>
                </tr>
            </table>
            
            <input type="submit" value="Log in">
        </form>
abc;

您将需要为每个服务器进行以下配置设置:

$cfg['Servers'][$i]['signon_user'] = 'user for this server';
$cfg['Servers'][$i]['signon_password'] = 'password for this server;
$cfg['Servers'][$i]['SignonSession'] = 'SignonSession';
$cfg['Servers'][$i]['SignonCookieParams'] = [];
$cfg['Servers'][$i]['SignonURL'] = 'signon/?server=' . $i;
$cfg['Servers'][$i]['LogoutURL'] = 'signon/?logout=1';

欢迎提出改进建议!

相关内容