我正在尝试使用 Java 连接到具有两步验证登录的 Linux 服务器。我正在使用 JSch 库,这是我到目前为止得到的代码:
session = jsch.getSession(username, ip);
Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(password);
session.connect();
System.out.println("Connected to " + ip);
显然,当我运行此脚本时,我收到“身份验证失败”错误,因为我尚未输入身份验证密钥。那么如何使用验证码登录呢?如果这是不可能的,有人可以建议一个具有此功能的库。
我最终解决了这个问题,你必须实现 UserInfo 和 UIKeyboardInteractive。使用 PromptKeyboardInteractive 方法,使其返回身份验证密钥,如以下对我有用的代码所示:
import java.security.InvalidKeyException;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;
public class UserAuthKI{
public static void main(String[] arg){
try{
JSch jsch=new JSch();
String host="";
String user="";
Session session=jsch.getSession(user, host, 22);
// username and passphrase will be given via UserInfo interface.
UserInfo ui=new MyUserInfo();
session.setUserInfo(ui);
session.connect();
Channel channel =session.openChannel("exec");
((ChannelExec)channel).setCommand("echo 'hello'");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
}
catch(Exception e){
System.out.println(e);
}
}
public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{
public String getPassword(){ return "passwordHere"; }
public boolean promptYesNo(String str){
return true;
}
public String getPassphrase(){return null;}
public boolean promptPassphrase(String message){ return false; }
public boolean promptPassword(String message){
return true;
}
public void showMessage(String message){
System.out.println(message);
}
public String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo){
System.out.println("destination: "+destination);
System.out.println("name: "+name);
System.out.println("instruction: "+instruction);
System.out.println("prompt.length: "+prompt.length);
String[] str = new String[1];
if(prompt[0].contains("Password:")){
str[0] = getPassword();
}
else if(prompt[0].contains("Verification code: ")){
try {
str[0] = PasswordUtils.verify_code("CODEHERE");
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
str = null;
}
return str;
}
}
}
(PasswordUtils.verif_code() 是生成密钥的静态方法)