从java访问SMB2.1或SMB3共享?

Mot*_*oth 5 java smb

由于Windows 2012R2不再支持SMB1协议而没有一些注册表黑客,使用Java中的SMB共享是否有任何成功,只支持SMB2.1或SMB3?JCIFS库显然只是SMB1,所以它出来了.我看到微软有一个用于Azure的Java库,但这似乎是利用服务而不是SMB.

Mic*_*ili 9

我发现这个包可以用于SMB2和SMB3,名为smbj看看这个:https://github.com/hierynomus/smbj

  • 请不要只是发布一些非现场资源的链接作为答案.至少在答案本身中演示[它如何解决问题](http://meta.stackoverflow.com/a/251605). (3认同)
  • 我从 JCIFS 切换到 smbj 并为其编写了一个包装器(以面向文件/目录的方式包含最常用的功能):https://github.com/swaechter/smbjwrapper (2认同)

Aiv*_*ras 6

扩展@Breakidi 答案,我刚刚在 Android 上使用了hierynomus/smbjv0.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());
}
Run Code Online (Sandbox Code Playgroud)

上传文件

确保在调用openFilea时设置正确的标志DiskShare(通过在课程外查看源代码):

// 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();
}
Run Code Online (Sandbox Code Playgroud)


小智 5

Visuality Systems 目前正在开发 JNQ,它是基于 Java 的 SMB,支持 3.1.1。由于该需求包含对 Java 1.4 的向后支持,因此开发进展缓慢。SMB 客户端将在即将到来的夏天某个地方可用,服务器将稍后提供。