The application of SMB in Java

Keywords: Java Windows ftp Unix

Catalog

SMB service operations

I Introduction to SMB

SMB (full name is Server Message Block) is a protocol name, which can be used for Web connection and information communication between client and server. As a file sharing and transferring protocol in LAN, SMB is often used as a platform for the research on the secure transfer of shared files.
The Windows operating system includes both client and server SMB protocol support. Microsoft provides an open source version of SMB for the Internet, which is the common internet file system CIFS. CIFS is more flexible than existing Internet applications such as FTP. For UNIX systems, you can use a shared software called Samba.

Ⅱ SMB configuration

2.1 Windows SMB

2.1.1 configuration service

On the local computer, take Windows10 as an example: in the control panel, programs and functions, enable or disable Windows functions, SMB 1.0/cifs file sharing supportcheck SMB 1.0/CIFS Client and SMB 1.0/CIFS Server

2.1.2 verification service

After opening, verify whether the SMB is opened correctly: in the DOS command window, enter the program with PowerShell command, enter get smbserverconfiguration | select enablesmb1protocol, and enable smb2protocol to view the service status, as shown in the figure:

2.1.3 shared files

Create a new test file on disk D: D:\Test\SmbTest\GoalTest, right-click menu - > grant access rights - > select a user for authorization, as shown in the figure:

After being authorized to the user, you will be prompted that your folder has been shared. Enter the sharing connection \ \ DESKTOP-D5DVINV\Test prompted by the pop-up window in the DOS window to enter the shared folder. Right click the shared folder to set the access password, change the access user, etc.

Ⅲ add SMB dependency

Add SMB service related dependencies in pom.xml:

<!-- Quote SmbFile Class jar package  -->
<dependency>
       <groupId>jcifs</groupId>
       <artifactId>jcifs</artifactId>
       <version>1.3.17</version>
</dependency>

Ⅳ path format

In Java, there are three types of SMB path request formats:

  • If sharing without password, the format is similar: SMB: / / IP / sharefolder (for example: smb://192.168.0.77/test)
  • If you need a user name and password, the format is similar: SMB: / / username: password @ IP / sharefolder (example: smb://chb:123456@192.168.0.1/test)
  • If the user name and password are similar to the domain name, the format is: smb: domain name; user name: password @ destination IP / folder / file name. XXX (example: smb://orcl;wangjp:Password123@192.168.193.13/Test)

Ⅴ operation sharing

After the above steps, we have completed the establishment of an SMB file server on Windows and the necessary preparations. The next step is a simple code link. The logic of uploading and downloading is also relatively simple. The operation of the SMB shared file is actually to process the SmbFile object.

import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;
import org.springframework.util.FileCopyUtils;
import java.io.*;
/**
 * @author: Create By WangJP
 * @description: SMB Service operation related
 * @date: 2020/1/1
 */
public class Demo {

    private static final String SMB_SHARE_FOLDER = "smb://username:password@192.168.1.103/Test/";
    private static final String SHARE_FOLDER_PATH = "SmbTest\\GoalTest";
    private static final String FILE_NAME = "test.txt";
    private static final String LOCAL_DIR = "D:\\LocalTest";

    public static void main(String[] args) {
        downloadSmbFile(SMB_SHARE_FOLDER, SHARE_FOLDER_PATH, FILE_NAME, LOCAL_DIR);
        uploadFile(SMB_SHARE_FOLDER, SHARE_FOLDER_PATH, FILE_NAME, LOCAL_DIR);
    }

    /**
     * Download files from SMB shared folder to local
     * @param remoteUrl       SMB Request path Url
     * @param shareFolderPath Full path of SMB target file in shared folder
     * @param fileName        file name
     * @param localDir        Local folder
     */
    public static void downloadSmbFile(String remoteUrl, String shareFolderPath, String fileName, String localDir) {
        InputStream in = null;
        OutputStream out = null;
        try {
            SmbFile smbfile = new SmbFile(remoteUrl + shareFolderPath + File.separator + fileName);
            File localFile = new File(localDir + File.separator + fileName);
            in = new BufferedInputStream(new SmbFileInputStream(smbfile));
            out = new BufferedOutputStream(new FileOutputStream(localFile));
            FileCopyUtils.copy(in, out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeStreanm(in, out);
        }
    }

    /**
     * Upload files from the local folder to the SMB shared folder (similar to downloading)
     * @param remoteUrl       SMB Request path Url
     * @param shareFolderPath Full path of SMB target file in shared folder
     * @param fileName        file name
     * @param localDir        Local folder
     */
    private static void uploadFile(String remoteUrl, String shareFolderPath, String fileName, String localDir) {
        InputStream in = null;
        OutputStream out = null;
        try {
            SmbFile smbfile = new SmbFile(remoteUrl + shareFolderPath + File.separator + fileName);
            File localFile = new File(localDir + File.separator + fileName);
            in = new BufferedInputStream(new FileInputStream(localFile));
            out = new BufferedOutputStream(new SmbFileOutputStream(smbfile));
            FileCopyUtils.copy(in, out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeStreanm(in, out);
        }
    }

    private static void closeStreanm(InputStream in, OutputStream out) {
        try {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

One of the business requirements in my work is to detect the existence of a File in the SMB shared directory. Through the example of downloading and uploading, I learned that obtaining the SmbFile object requires the construction of specific attributes (url canon, etc.). There are many processing methods similar to the File object. The code examples are as follows:

 /**
     * Verify that the SMB shared file exists
     * @param remoteUrl       SMB Request path Url
     * @param shareFolderPath Full path of SMB target file in shared folder
     * @param fileName        file name
     * @return true:false exists: does not exist
     */
    public static boolean checkSmbFile(String remoteUrl, String shareFolderPath, String fileName) {
        boolean result = false;
        try {
            SmbFile smbfile = new SmbFile(remoteUrl + shareFolderPath + File.separator + fileName);
            result = smbfile.exists();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

Ⅵ login verification

The purpose of SMB login verification is to solve the problem of special characters in account passwords (such as escape characters and specific characters in links). Account passwords with special characters often report the following exceptions:

Connected to the target VM, address: '127.0.0.1:54593', transport: 'socket'
jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad password.

In order to build a legal SmbFile object, we need to perform login verification first, and then try to build the object:

private static String domainip = "192.168.170.13";
private static String username = "username";
private static String password = "password";
private static String remoteurl = "smb://192.168.170.13/share";
//Perform account IP address login verification
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(domainip, username, password);  
SmbFile smbfile = new SmbFile(remoteurl+"//"+folderpath,auth);

Posted by tridean34 on Wed, 29 Jan 2020 02:41:12 -0800