403 error while file download API Call
AnsweredHello,
I have a JWT authenticated Java app. I can access all the folders info and their contents as my app is a co-owner of the root folder. However, when i try to download the files i get an access_denied_insufficient_permissions - Access denied - insufficient permission error.
I tried to re-authorize the app, but it didn`t help.
com.box.sdk.BoxAPIResponseException: The API returned an error code [403 | dte3alfvcmibfwld] access_denied_insufficient_permissions - Access denied - insufficient permission at com.box.sdk.BoxAPIResponse.(BoxAPIResponse.java:90) at com.box.sdk.BoxJSONResponse.(BoxJSONResponse.java:32)
my download function is :
public static byte[] downloadFile(BoxFile file) { try (ByteArrayOutputStream outstream = new ByteArrayOutputStream()){ file.download(outstream); byte[] bytes = outstream.toByteArray(); return bytes; } catch (IOException e) { System.err.println("Couldn`t download file." + e.toString()); } return null; }
Please advise.
-
The write scope was disabled. After enabling it I was able to download the files.
However, it is a weird situation because the the action I am interested in is "view" only and not "edit".
Does allowing the "write" scope implies that my application will be able to change contents or move files?
thanks.
-
,
Correct, adding the write scope will mean that your app will have those elevated privileges to make content change / move requests.
If you'd like to keep the application tightly scoped for just downloading, I have something that might work. I haven't tested it for specifically this case, but you could technically use the token downscoping endpoint to take your wider scoped access token and downscope it for read only with download permissions. What I'm thinking is specifically setting it for these two scopes:
- item_download
- root_readonly
Here are the wider set of scopes that you can set for and here are some samples for making downscope token requests with the different SDKs.
-
,
I was working on a sample recently for this same issue and wanted to provide some more context. It appears that if you set the token downscope scopes to only 'item_read' it'll allow the download. Here's a sample in Node that shows you that process:
'use strict'; // Initialize packages const appConfig = require('./config.js'); // Auth keys and Box SDK const boxSDK = appConfig.boxSDK; // Box SDK const fs = require('fs'); // File system accessor for RSA keys const util = require('util'); // Deep inspection of objects // Fetch private key for signing the JWT const secret = fs.readFileSync(appConfig.privateKeyPath); const sdk = new boxSDK({ clientID: appConfig.jwtClientId, clientSecret: appConfig.jwtClientSecret, appAuth: { keyID: appConfig.publicKeyId, privateKey: secret, passphrase: appConfig.keyPass } }); const client = sdk.getAppAuthClient('enterprise', appConfig.enterpriseId); // Define resource and scopes that downscoped token should have access to const scopes = 'item_read'; const fileId = '314831637088' const resource = `https://api.box.com/2.0/files/${fileId}` // Perform token exchange to get downscoped token client.exchangeToken(scopes, resource).then((dsToken) => { const dsclient = sdk.getBasicClient(dsToken.accessToken); //FILE DOWNLOAD dsclient.files.getReadStream(fileId, null, function(error, stream) { if (error) { console.error(error); } // write the file to disk var output = fs.createWriteStream('/Users/jleblanc/Desktop/tempdoc.txt'); stream.pipe(output); }); }).catch((err) => { console.error(err); });
For the data written, it'll be items such as access stats (# of downloads in this case).
Hope that helps,
Jon
-
Hi, I'm trying to download file using Box-api download file in node.js from here https://developer.box.com/reference and in response->body or body I'm getting the raw data of the file but I'm not sure how to convert that raw data into Readable or writable stream in Node.js. Can you help me in that.
Thanks in advance
-
Hi ,
Yep, something like the following should work, where fileID is the Box file ID and the tempdoc.txt item is the new file created locally from the download.
client.files.getReadStream(fileId, null, function(error, stream) { if (error) { console.log(error); } // write the file to disk var output = fs.createWriteStream('./tempdoc.txt'); stream.pipe(output); });
-
Hi
Thanks for your response but I'm not using box-node-sdk because our project is in Typescript as box-sdk don't have @types files I have to use API(https://api.box.com/2.0/files/file_id/content). Documentation says it returns the raw data and an url to download the file but I'm getting only the raw data in the response. Can you help me how to convert that raw data into a file.
Thanks again.
Please sign in to leave a comment.
Comments
8 comments