<p>我意识到这个问题已经快4岁了,但是我碰到了同样的问题,找到了一个可行的解决方案!</p>
<p>引用文档:<a href="http://docs.paramiko.org/en/2.4/api/transport.html" rel="nofollow noreferrer">http://docs.paramiko.org/en/2.4/api/transport.html</a></p>
<p>在文档中,在<code>connect()</code>方法下提到:</p>
<blockquote>
<p>This is a shortcut for start_client, get_remote_server_key, and Transport.auth_password or Transport.auth_publickey. </p>
</blockquote>
<p>因此,如果需要进行多因素身份验证,就不能使用<code>connect()</code>,必须使用上述方法手动协商并触发两种身份验证,在进行密码身份验证之前先使用密钥身份验证。</p>
<p>下面的片段对我有用!</p>
<pre><code>host = "some-host"
port = 22
sftp_key = "/some-key"
username = "some-user"
password = "some-pass"
sftp_key = paramiko.RSAKey.from_private_key_file(sftp_key)
transport = paramiko.Transport((host, port))
transport.start_client(event=None, timeout=15)
transport.get_remote_server_key()
transport.auth_publickey(username, sftp_key, event=None)
transport.auth_password(username, password, event=None)
sftp = paramiko.SFTPClient.from_transport(transport)
</code></pre>
<p>并将整个过程封装在一个函数中,以处理几乎任何可以抛出的SFTP服务器。我的错误处理被省略了,因为这里没有意义。。。</p>
<pre><code>#Auth types: user_pass, key_only, key_and_pass
#You can pass a junk string in for password or sftp_key if not used
def connect_to_sftp(host, port, username, password, sftp_key, auth_type):
try:
transport = paramiko.Transport((host, port))
if auth_type == "key_and_pass":
sftp_key = paramiko.RSAKey.from_private_key_file(sftp_key)
transport.start_client(event=None, timeout=15)
transport.get_remote_server_key()
transport.auth_publickey(username, sftp_key, event=None)
transport.auth_password(username, password, event=None)
#transport.connect(username = username, password = password, pkey = sftp_key)
elif auth_type == "key_only":
sftp_key = paramiko.RSAKey.from_private_key_file(sftp_key)
transport.connect(username = username, pkey = sftp_key)
elif auth_type == "user_pass":
transport.connect(username = username, password = password)
else:
## Do your own error handling :)
print "uh-oh!"
sftp = paramiko.SFTPClient.from_transport(transport)
except Exception, e:
## Do your own error handling :)
print "uh-oh!"
return sftp, transport
</code></pre>