1

有没有人最近在双因素身份验证(私钥和密码)中使用 phpseclib/Flysystem/SFTP 的经验?

我昨天刚遇到这个问题,需要修复。我的搜索导致我:

它已经 3 岁了,而且 phpseclib 似乎仍然没有修复——或者是吗?

无论如何在不修改基础库的情况下让它工作吗?

使用:“league/flysystem-sftp”:“~1.0-stable”,它使用“phpseclib/phpseclib”:“~2.0”

4

2 回答 2

2

这是我找到的解决方案。它实际上很简单。

我通过双重身份验证遵循@neubert 的想法:扩展了 SftpAdapter,并重载了 login() 方法:

<?php
use LogicException;

/**
 * Class SftpAdapter
 *
 * We're going to overload SftpAdapter in order to fix a bug handling key AND password authentication
 *
 * @package App\MyPackage
 */
class SftpAdapter extends \League\Flysystem\Sftp\SftpAdapter
{
    /**
     * Login.
     *
     * @throws LogicException
     */
    protected function login()
    {
        if (! $this->connection->login($this->username, $this->getPrivateKey())
            && ! $this->connection->login($this->username, $this->getPassword())) {
            throw new LogicException('Could not login with username: '.$this->username.', host: '.$this->host);
        }
    }

}

现在。有用。这里的缺点是您现在依赖于 SftpAdapter(即没有可注入性)。但是,由于这是一个非常具体的用例,我们可以使用它。

于 2016-08-29T18:13:10.390 回答
1

三年前我回答了这个问题,我仍然会给出同样的答案。

SFTP 服务器同时使用密码和公钥身份验证的情况很少见。我的猜测是,您最有可能拥有的是受密码保护的私钥。如果是这样,您可以这样登录:

<?php
include('Net/SFTP.php');
include('Crypt/RSA.php');

$sftp = new Net_SFTP('www.domain.tld');
$key = new Crypt_RSA();
$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
if (!$sftp->login('username', $key)) {
    exit('Login Failed');
}

print_r($sftp->nlist());
?>

如果确实您的服务器确实在执行以下两项操作,则应该可以:

<?php
include('Net/SFTP.php');
include('Crypt/RSA.php');

$sftp = new Net_SFTP('www.domain.tld');
$key = new Crypt_RSA();
$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
if (!$sftp->login('username', $key) && !$sftp->login('username', 'password')) {
    exit('Login Failed');
}

print_r($sftp->nlist());
?>

请注意,这是针对 1.0 版本的。如果您使用的是 2.0 版本,则需要对代码进行一些更改。由于您还没有发布自己的代码,因此不可能知道您使用的是什么版本。

此外,在审查那个 3.5 年前的帖子时......看起来有问题,但现在应该修复这些问题。我自己用 phpseclib 完成了多因素身份验证,没有问题。你有理由相信它不起作用吗?

编辑:对于 2.0,你需要这样做:

对于 2.0,您需要这样做:

$sftp = new SFTP('www.domain.tld');
$key = new RSA();
//$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
if (!$sftp->login('username', $key) && !$sftp->login('username', 'password')) {
    exit('Login Failed');
}

print_r($sftp->nlist());
于 2016-08-29T15:44:38.053 回答