0

I have to create and fill a CSV file with some data, and then place it into the username and password protected remote location on a client's computer. I'm using apache-commons CSVPrinter to write the file. A scheduled job writes the file, but I can't seem to pass the authentication process.

UserAuthenticator auth = new StaticUserAuthenticator(domain, userName, password);
FileSystemOptions opts = new FileSystemOptions();

DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);
FileObject fo = VFS.getManager().resolveFile(exportLocation + fileName, opts);

BufferedWriter writer = Files.newBufferedWriter(Paths.get(fo.getURL().getPath()), StandardCharsets.UTF_8);

CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withDelimiter(';'));

I'm getting a java.nio.file.AccessDeniedException with the upper code. Can anyone advise me how to approach the issue, and tell me what I am doing wrong?

**************************************************** EDIT ********************************************************

I have updated the code to:

UserAuthenticator auth = new StaticUserAuthenticator(domain, userName, password);
FileSystemOptions opts = new FileSystemOptions();

DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);
FileObject fo = VFS.getManager().resolveFile(exportLocation + fileName, opts);
FileContent fileContent = fo.getContent();

CSVPrinter csvPrinter = new CSVPrinter((Appendable) fileContent.getOutputStream(),
                    CSVFormat.DEFAULT.withDelimiter(';'));

I got rid of the BufferedWriter and replaced it with a FileContent instance. Now I'm getting the org.apache.commons.vfs2.FileSystemException: Could not write to "file:////*PATH*/*TO*/*CSV_FILE*.csv".

Now, my .csv file path contains the two backslashes at the beginning because if I remove them, the line FileObject fo = VFS.getManager().resolveFile(exportLocation + fileName, opts); will produce the following exception: org.apache.commons.vfs2.FileSystemException: Could not find file with URI "*PATH*\*TO*\*CSV_FILE*.csv" because it is a relative path, and no base URI was provided. Naturally, this happens because the two backslashes point to a file in a folder rather than the URI.

My problem now is: how can I keep the backslashes for the required line, and remove them when writing to a file in this line: CSVPrinter csvPrinter = new CSVPrinter((Appendable) fileContent.getOutputStream(), CSVFormat.DEFAULT.withDelimiter(';'));?

Plus, I can see now that this last exception was caused by this: java.io.FileNotFoundException: *PATH*\*TO*\*CSV_FILE*.csv (Access is denied) which would mean that I still haven't been able to pass the authentication.

mdenci
  • 297
  • 2
  • 6
  • 17

1 Answers1

1

Well, I've given up this approach, so I've tried using jcifs, and got it working.

CIFSContext base = SingletonContext.getInstance();
CIFSContext authed1 = base.withCredentials(new NtlmPasswordAuthenticator(domain, userName, password));

SmbFile sFile = new SmbFile("smb://" + exportLocation + fileName, authed1);
SmbFileOutputStream sfos = new SmbFileOutputStream(sFile);
OutputStreamWriter out = new OutputStreamWriter(sfos);

CSVPrinter csvPrinter = new CSVPrinter(out, CSVFormat.DEFAULT.withDelimiter(';'));

Sorry I couldn't figure out what was wrong with my apache-commons-vfs code.

mdenci
  • 297
  • 2
  • 6
  • 17
  • The problem using JCIFS is that is utilize only the SMB1 dialect that most of the OSes are not supporting anymore. So if one day your app stop work you will know why. You can search in the network for other SMB implementations that support the SMB2 and SMB3 dialects – Eliad Cohen Feb 07 '20 at 08:12
  • @EliadCohen I've used the JCIFS-NG which has support for SMB2 – mdenci Feb 07 '20 at 08:26
  • @EliadCohen: there is also jcifs 2.x which forks from jcifs-ng and supports SMB 2.0, even some parts of SMB 3.0. See https://github.com/codelibs/jcifs – Jan Zyka Sep 25 '20 at 19:58