簡體   English   中英

從 Java 訪問 SMB2.1 或 SMB3 共享?

[英]Accessing SMB2.1 or SMB3 share from Java?

由於 Windows 2012R2 在沒有一些注冊表黑客的情況下不再支持 SMB 1 協議,有沒有人在 Java 中使用 SMB 共享成功,其中只支持 SMB 2.1 或 SMB 3?

JCIFS 庫顯然只是 SMB 1,所以它已經過時了。 我看到微軟有一個用於 Azure 的 Java 庫,但這似乎是在利用服務而不是 SMB。

我找到了這個可以與SMB2和SMB3一起使用的包,名為smbj 看看這個: https : //github.com/hierynomus/smbj

擴展@Breakidi 答案,我剛剛在 Android 上使用了hierynomus/smbj v0.2.0並添加了 SMB2 支持。 它聲稱支持 SMB2 和 SMB3,盡管類僅引用 SMB2 版本,不確定,也許無關緊要。

測試

我已經在一種情況下對運行 SMB2 的盒子進行了測試,然后在另一種情況下 SMB2 和 SMB3 都打開。 不過,我無法禁用 SMB2 並單獨測試 SMB3。

充氣城堡/海綿城堡

在我的情況下需要使用 Spongycastle(很可能是因為 Android),因為類路徑中缺少所需的 MD4 依賴項。 我在連接到 SMB 的班級中使用了它:

import org.spongycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
<...>
static {
    Security.addProvider(new BouncyCastleProvider());
}

上傳文件

確保在DiskShare上調用openFile時設置正確的標志(通過查看源代碼):

// required imports
import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.msfscc.FileAttributes;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2CreateOptions;
import com.hierynomus.mssmb2.SMB2ShareAccess;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.common.SMBApiException;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashSet;
...
// connection params
String sambaDomain = null; // can be null
String sambaUsername = "iamuploader";
String sambaPass = "mysecret";
String sambaIP = "192.168.1.236";
String sambaSharedPath = "sharedfolder";

...
// upload method
// usage: upload("file/whithin/folder.txt", fileBytes);
public void upload(String filename, byte[] bytes) throws IOException {

    SmbConfig cfg = SmbConfig.builder().build();
    SMBClient client = new SMBClient(cfg);
    Connection connection = client.connect(sambaIP);
    Session session = connection.authenticate(new AuthenticationContext(sambaUsername, sambaPass.toCharArray(), sambaDomain));
    DiskShare share = (DiskShare) session.connectShare(sambaSharedPath);

    // this is com.hierynomus.smbj.share.File !
    File f = null;
    int idx = filename.lastIndexOf("/");

    // if file is in folder(s), create them first
    if(idx > -1) {
        String folder = filename.substring(0, idx);
        try {
            if(!share.folderExists(folder)) share.mkdir(folder);
        } catch (SMBApiException ex) {
            throw new IOException(ex);
        }

    }

    // I am creating file with flag FILE_CREATE, which will throw if file exists already
    if(!share.fileExists(filename)){
        f = share.openFile(filename,
                new HashSet<>(Arrays.asList(AccessMask.GENERIC_ALL)),
                new HashSet<>(Arrays.asList(FileAttributes.FILE_ATTRIBUTE_NORMAL)),
                SMB2ShareAccess.ALL,
                SMB2CreateDisposition.FILE_CREATE,
                new HashSet<>(Arrays.asList(SMB2CreateOptions.FILE_DIRECTORY_FILE))
        );
    }

    if(f == null) return null;

    OutputStream os = f.getOutputStream();
    os.write(bytes);
    os.close();
}

Visuality Systems 目前正在開發 JNQ,它是基於 Java 的 SMB,支持 3.1.1。 由於該需求包含對 Java 1.4 的向后支持,因此開發進展緩慢。 SMB 客戶端將在即將到來的夏天某個地方可用,服務器將稍后提供。

使用hierynomus/smbj v0.3.0 時,出現“ ClassNotFoundException: sun.security.provider.MD4 ”之類的異常,然后我使用以下代碼解決問題。

SmbConfig cfg = SmbConfig.builder().
                withMultiProtocolNegotiate(true).
                withSecurityProvider(new JceSecurityProvider(new BouncyCastleProvider())).
                build();
SMBClient client = new SMBClient(cfg);

還有一個支持 SMB2 的庫: https : //github.com/AgNO3/jcifs-ng

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM