美文网首页
SFtp验证

SFtp验证

作者: 风居住的街道_83df | 来源:发表于2020-08-23 20:24 被阅读0次

    通过SFtp的方式访问服务器的文件,一定程度上对服务器的安全性而言有比较大的提升。比方说:服务器只开启部分目录下的访问权限,或者只开启读权限等。

    引入依赖

    <dependency>

    <groupId>com.jcraft</groupId>

    <artifactId>jsch</artifactId>

    <version>0.1.54</version>

    </dependency>

    常见的有两种登录方式:

    1. ip账号密码

    2.密钥key方式

    代码及方法

    package com.hf.zuul.zuul.sftps;

    import com.jcraft.jsch.*;

    import java.io.*;

    import java.util.ArrayList;

    import java.util.List;

    import java.util.Properties;

    import java.util.Vector;

    /**

    * @author hanfei

    * @Date 2020/8/23

    */

    public class SFtpMethod {

    private ChannelSftpsftp;

        private Sessionsession;

        private Stringip;

        private int port;

        private StringuserName;

        private Stringpassword;

        private static final StringfolderPath ="/usr/local/20200805";

        private static final StringfileName ="check_credit_apply__mcaus_6eqfy";

        public SFtpMethod(String ip, int port, String userName, String password) {

    this.ip = ip;

            this.port = port;

            this.userName = userName;

            this.password = password;

        }

    /**

    * 连接服务器,账号密码

    */

        public void connection(){

    JSch jSch =new JSch();

            try {

    session = jSch.getSession(userName, ip, port);

                session.setPassword(password);

                Properties properties =new Properties();

                properties.put("StrictHostKeyChecking", "no");

                session.setConfig(properties);

                session.connect();

                sftp = (ChannelSftp)session.openChannel("sftp");

                sftp.connect();

            }catch (JSchException e) {

    e.printStackTrace();

            }

    }

    /**

    * 连接服务器,密钥方式

        * @param passphrase    密钥口令

        * @param keyFile  密钥路径

    */

        public void connection(String passphrase, String keyFile){

    JSch jSch =new JSch();

            try {

                jSch.addIdentity(keyFile);

                UserInfo userInfo =new MyUserInfo(passphrase);

                session = jSch.getSession(userName, ip, port);

                session.setUserInfo(userInfo);

                session.setTimeout(300000);

                Properties properties =new Properties();

                properties.put("StrictHostKeyChecking", "no");

                session.setConfig(properties);

                session.connect();

                sftp = (ChannelSftp)session.openChannel("sftp");

                sftp.connect();

            }catch (JSchException e) {

    e.printStackTrace();

            }

    }

    /**

    * 获取所有文件名

    */

        public ListgetAllFileNames(){

    connection();

            List fileNames =new ArrayList<>();

            try {

    Vector entries =sftp.ls(folderPath);

                for (ChannelSftp.LsEntry entrie :entries) {

    String name = entrie.getFilename();

                    if (!".".equals(name) && !"..".equals(name)) {

    fileNames.add(name);

                    }

    }

    }catch (SftpException e) {

    e.printStackTrace();

            }finally {

    close();

            }

    return fileNames;

        }

    /**

    * 获取所有文件名,密钥方式

    */

        public ListgetAllFileNames(String passphrase, String keyFile){

    connection(passphrase, keyFile);

            List fileNames =new ArrayList<>();

            try {

    Vector entries =sftp.ls(folderPath);

                for (ChannelSftp.LsEntry entrie :entries) {

    String name = entrie.getFilename();

                    if (!".".equals(name) && !"..".equals(name)) {

    fileNames.add(name);

                    }

    }

    }catch (SftpException e) {

    e.printStackTrace();

            }finally {

    close();

            }

    return fileNames;

        }

    /**

    * 按行读取文件

        * @return

        */

        public ListreadByLine(){

    connection();

            List lines =new ArrayList<>();

            try {

    sftp.cd(folderPath);

                InputStream in =sftp.get(fileName);

                BufferedReader buffer =new BufferedReader(new InputStreamReader(in));

                String line ="";

                while ((line = buffer.readLine()) !=null) {

    lines.add(line);

                }

    }catch (SftpException | IOException e) {

    e.printStackTrace();

            }finally {

    close();

            }

    return lines;

        }

    /**

    * 下载文件

        * @param localDir

        * @return

        */

        public FiledownLoadFile(String localDir){

    connection();

            File file =null;

            OutputStream out;

            try {

    file =new File(localDir);

                sftp.cd(folderPath);

                out =new FileOutputStream(file);

                sftp.get(fileName, out);

            }catch (SftpException | FileNotFoundException e) {

    e.printStackTrace();

            }finally {

    close();

            }

    return file;

        }

    public void close(){

    if (sftp !=null) {

    sftp =null;

            }

    if (session !=null) {

    session =null;

            }

    }

    public static void main(String[] args) {

    SFtpMethod sFtpMethod =new SFtpMethod("",22,"","");

            // 显示所有文件名

            List fileNames = sFtpMethod.getAllFileNames();

            for (String fileName : fileNames) {

    System.out.println(fileName);

            }

    //        // 按行读取文件输出

            List lines = sFtpMethod.readByLine();

            for (String line : lines) {

    System.out.println(line);

            }

    //        // 下载文件

            sFtpMethod.downLoadFile("/Users/Downloads/check_credit_apply__mcaus_6eqfy");

    //        // 密钥方式

            List fileNamess = sFtpMethod.getAllFileNames("","");

            for (String fileName : fileNamess) {

    System.out.println(fileName);

            }

    }

    /**

    * 身份信息

    */

        class MyUserInfoimplements UserInfo{

    private Stringpassphrase;

            public MyUserInfo(String passphrase) {

    this.passphrase = passphrase;

            }

    @Override

            public StringgetPassphrase() {

    return null;

            }

    @Override

            public StringgetPassword() {

    return null;

            }

    @Override

            public boolean promptPassword(String s) {

    return false;

            }

    @Override

            public boolean promptPassphrase(String s) {

    return false;

            }

    @Override

            public boolean promptYesNo(String s) {

    return false;

            }

    @Override

            public void showMessage(String s) {

    }

    }

    }

    通过秘钥方式进行sftp连接,需要在本地生成秘钥:ssh-keygen,然后一路回车或两次输入passphrase。接着在.ssh文件夹下使用命令 ssh-copy-id 账号@118.XX.XX.XX(目标服务器ip),将公钥加入到目标服务器的authorized_keys中,接着登录服务器进行.ssh目录,chmod 664 authorized_keys,赋予权限。如果是mac系统可以使用ssh-keygen -e。

    秘钥文件路径keyFile是本地的私钥路径(包含文件名)。下面简单验证一下:

    我保持本地私钥文件位置正确的情况下,改变服务器的私钥位置或名字,仍能够正常访问。

    在秘钥验证时,我将keyFile路径设置为一个本地不存在的文件的路径,报错如下:

    本地私钥不存在

    我再把参数keyFile变为一个本地存在的文件,但不是私钥文件位置。报错如下:

    私钥无效

    我将passphrase参数设置任意一个值,还是可以成功连接。这一点很疑惑,不知道为啥,但成功了就高兴。

     properties.put("StrictHostKeyChecking", "no");StrictHostKeyChecking有三种选项,no、ask、yes。这三个选项代表了不同的级别,yes最高,no最低。在ssh访问服务器的过程中,会将服务器的公钥保存到本地的~/.ssh/known_hosts中,每次访问服务器都会检查此公钥是否发生变化,如果发生了变化,则这三个选项的设置如下:

    no:自动将服务器新的公钥保存到known_hosts中,并发出一个警告;

    ask:拒绝连接到服务器,且发出一个警告;

    yes:拒绝连接到服务器,且不发出警告;

    一般在测试环境下使用no,生产环境使用yes或ask。

    参考:https://www.jianshu.com/p/090792e12518

    https://juejin.im/post/6844904004493770759

    相关文章

      网友评论

          本文标题:SFtp验证

          本文链接:https://www.haomeiwen.com/subject/wctwjktx.html