Roles Permissions on Files - Preventing Access for NotAuthenticatedUser Shuts Off Access for Logged in User Too

Hello, my app id is 8149FCCE-07DA-F988-FFBB-6154872C9500.

On a DIRECTORY called app-files/compliance, I turned off Read access to the NotAuthenticatedUser role. It immediately stopped access for a non-logged-in user, as expected. But it also prevents access for my logged-in JS user too. After login, I call getUserRoles and it returns an array of “AuthenticatedUser” and “JSUser”. But trying to open any file in the directory returns a 4000 “no permissions” error. When I turn Read access back on, the app can read all files in the directory, so I know the problem is with my understanding of the Roles Permissions behavior. What am I missing? The documentation has diverged a bit from current functionality - I don’t see a distinction being made any more between inheriting and explicitly granting access - but the Read flag has a red X and everything else is a green check.

Thank you,
Kelly

I had the same discussion without a satisfying solution: https://support.backendless.com/t/cant-get-file-access-permission-for-authenticateduser-working

Hello @Kelly_Oglesby ,

I can not reproduce the issue on your app. I have created a folder `` and deny permission for NotAuthenticatedUser, then I have logged in test user 123:

curl 'https://api.backendless.com/8149FCCE-07DA-F988-FFBB-6154872C9500/<api-key>/users/login' \
  -H 'Content-Type: application/json' \
  --data-raw '{"login":"123","password":"123qwe"}' -i

Then list folder:

 curl https://api.backendless.com/8149FCCE-07DA-F988-FFBB-6154872C9500/<api-key>/files/support-test/inner -i -H "user-token:<token-from-previous-response>"
HTTP/1.1 200 OK
server: nginx
date: Wed, 23 Jun 2021 11:43:08 GMT
content-type: application/json
content-length: 559
access-control-allow-origin: *
access-control-allow-methods: POST, GET, OPTIONS, PUT, DELETE, PATCH
strict-transport-security: max-age=86400

[{"name":"other.log","createdOn":1624448414982,"updatedOn":1624448414982,"publicUrl":"https://backendlessappcontent.com/8149FCCE-07DA-F988-FFBB-6154872C9500/<api-key>/files/support-test/inner/other.log","size":1024,"url":"support-test/inner/other.log"},{"name":"test1.txt","createdOn":1624448405158,"updatedOn":1624448405158,"publicUrl":"https://backendlessappcontent.com/8149FCCE-07DA-F988-FFBB-6154872C9500/<api-key>/files/support-test/inner/test1.txt","size":1024,"url":"support-test/inner/test1.txt"}]

Hello @Klaas_Klever, you have another issue, and @mark-piller have suggested a solution for you

Hello,
Please excuse the long absence before responding.

I’m not calling the Files SDK directly. I store the Backendless-provided URL in the database, and set the url as the SRC attribute of an <img> element in an app that only authenticated users can see. For me, it fails 100% of the time if I turn off access permission for NotAuthenticatedUser. I guess GET requests for images don’t pass the user token, because I get a 400 (Bad Request) error on every attempt.

What security permissions would I use to allow ONLY the file’s owner, and anyone possessing a Role that I have granted them, to access files under the directory, please? Alternatively, is there a better way to display stored files in a logged-in app which works with the Files API?

Thank you,
Kelly

Hi Kelly,

You’re correct, when an image is fetched by a browser, the user-token header is not automatically added. A workaround for this would be turning on Cookie-based authentication on the Users > Login screen of Backendless console:

What this will do is instruct the Backendless backend to use a cookie instead of user-token to identify the user’s session. The cookie will be sent by the browser when it fetches the images. The important caveat is the URLs you use for the images should have the same domain name as the one you use to perform the login call.

Regards,
Mark

Thank you, Mark! While adding the cookie would solve the problem, I used a different solution that made some other features of my app more efficient. I was displaying the same images in multiple places in my app, just passing the backendless URL around and letting the browser do the heavy lifting, which required a round-trip for every instance. My solution was to not specify the image’s src until it is first displayed, then use “fetch” to download the image, passing the required user-token header, store it as a blob, then use URL.createObjectURL to point to that blob. The only challenge is to determine when to release the blob, which would be different in every application. I have a much better app now, so thanks again!

Kelly

If anyone else is interested…

            if (url.length) {
                let options = {
                    headers: {
                        "user-token": self.$db.getUserToken()
                    }
                }

                fetch(url, options)
                .then(res => {
                    return res.blob()
                })
                .then(blob => {
                    img.src = URL.createObjectURL(blob)
                })
                .catch(error => {
                    // fooey
                })
            }