phpMyAdmin 令牌认证系统

问题描述 投票:0回答:1

我最近有一个想法,使用存储在数据库中的登录凭据创建的令牌创建 PhpMyAdmin 的登录系统。 网址看起来像这样:

pma.example.com/index.php?token=WCxuFWj1QtGGapZhfSPS9Eo1Q9q666sR

令牌包含 32 个随机生成的字母数字字符。

所以我有一个用 Python 和 Flask 制作的 API,它与 PhpMyadmin 进行本地通信,并且不同的应用程序有两个路由:

  1. 127.0.0.1:4040/api/v1/create_token
    [POST] 此请求具有 JSON 参数
    database_host_id
    用于在 PhpMyAdmin 配置文件中定义的要连接的 MySQL 主机 ID,
    database_username
    是要连接的数据库用户所写的内容,最后
    database_host
    是数据库密码。响应有一个
    token
    参数,供客户端接收新生成的令牌。 发送和接收的 JSON 应如下所示:
JSON received by the API :
{
  "database_host_id": 1,
  "database_username": "pma",
  "database_password: "4wAyS8",
}

JSON sent to the client:
{
  "token": "WCxuFWj1QtGGapZhfSPS9Eo1Q9q666sR"
}
  1. 127.0.0.1:4040/api/v1/get_database
    [POST] 此请求有一个 JSON 参数
    token
    ,用于了解从哪个令牌检索连接信息。因此,响应将包含所有这些信息以及
    database_host_id
    database_username
    database_password
    。发送和接收的 JSON 应如下所示:
JSON received by the API :
{
  "token": "WCxuFWj1QtGGapZhfSPS9Eo1Q9q666sR"
}

JSON sent to the client :
{
  "database_host_id": 1,
  "database_username": "pma",
  "database_password: "4wAyS8",
}

有API固然好,但如果你不使用它,它就没用,所以我在PhpMyAdmin的源代码中搜索了身份验证系统是如何工作的。

我能理解:

  • /libraries/common.inc.php
    该脚本将在运行时使用所谓的
    AuthPlugin
    以及这段代码,然后由各个类用作登录界面:
$auth_plugin = Plugins::getAuthPlugin();
$auth_plugin->authenticate();
  • 我通过查看与此类相关的不同函数来了解
    AuthPlugin
    是什么。我推断
    libraries/classes/Plugins/Auth
    中的所有文件都是连接插件,并允许为我们在 PhpMyAdmin 配置文件中使用
    $cfg['Servers'][$i]['auth_type']
    定义的 MySQL 主机定义不同的连接方法。知道默认的认证类型是Cookie,我就去看了文件内容
    librairies/classes/Plugins/Auth/AuthenticationCookie.php

所以现在我必须修改

AuthenticationCookie.php
脚本,以便当
token
包含在 URL 中时,它可以从 API 检索信息,然后使用它连接到与该令牌关联的数据库。

这就是我陷入困境的地方,因为尽管我有 PHP 基础知识,但我无法让我正在做的事情发挥作用。尽管我尝试过,但我可以注意到,当我从 URL 检索令牌时,它根本不是定义的内容,就好像它是加密的一样。

这是我的问题:

  1. 即使 API 仅在本地通信,我是否应该加密密码?
  2. 我不应该只使用 SignOn 连接我的 MySQL 主机吗?
  3. 做我想做的事情安全吗?

信息:

  • PhpMyAdmin 版本:5.1.3

如果我能在推理过程中得到任何帮助或对我的问题有任何答案,我将不胜感激

php mysql authentication phpmyadmin
1个回答
2
投票

我最终制作了一个与我的服务器关联的登录脚本,该脚本从 URL 获取令牌,向 API 请求令牌信息,然后与其连接。它运行完美。

<?php
/**
 * Single signon for phpMyAdmin
 *
 * This is just example how to use session based single signon with
 * phpMyAdmin, it is not intended to be perfect code and look, only
 * shows how you can integrate this functionality in your application.
 */

declare(strict_types=1);

/* Use cookies for session */

ini_set('session.use_cookies', 'true');
/* Change this to true if using phpMyAdmin over https */
$secure_cookie = false;
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secure_cookie, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
//session_save_path('/foobar');
@session_start();

/* Was data posted? */
if (isset($_REQUEST['token'])) {
    $data = array(
        'token'=> $_REQUEST['token']
    );
    $payload = json_encode($data);
    $curl = curl_init('http://127.0.0.1:4040/api/v1/get_database');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $response = curl_exec($curl);

    curl_close($curl);

    $response = json_decode($response, true);
    
    /* Store there credentials */
    $_SESSION['PMA_single_signon_user'] = $response->database_username;
    $_SESSION['PMA_single_signon_password'] = $response->database_password;
    $_SESSION['PMA_single_signon_host'] = $_POST['host'];
    $_SESSION['PMA_single_signon_port'] = $_POST['port'];
    /* Update another field of server configuration */
    $_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];
    $_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
    $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";
    echo '<!DOCTYPE HTML>
<html 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">
<meta charset="utf-8">
<title>Loading...</title>
</head>
<body>';

    if (isset($_SESSION['PMA_single_signon_error_message'])) {
        echo '<p class="error">';
        echo $_SESSION['PMA_single_signon_error_message'];
        echo '</p>';
    }

    echo '
<h1>Loading...</h1>
</body>
</html>';
}

我知道它还没有完成,但我计划改进它。这就是我找到的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.