I want to upload files to Aamazon S3 service. I also want these files to be available to users to share but only with a link that no one else can guess. Something that Trello app does. Example of a link to a test file is
https://trello-attachments.s3.amazonaws.com/5215040bd3afdaa3500010db/525c8cf285f31702580008c0/39b48c4a06a309b2367b5e9c9bfe3593/test.txt
Is this being accomplished using Amazon S3 Encryption?
Client side encryption, as described in the link you posted means that the file that's stored on S3 will be encrypted before being sent to S3. When someone accesses the file, they won't be able to decrypt it without the correct keys and S3 will not have access to those keys.
To control access to files for a certain group of users, you can either use unique, non-guessable URLs like the Trello example you posted, or use S3 signed URLs as described here:
http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
Related
I'm trying to determine the best way to reference a Firebase Storage (Google Cloud Storage) file in a direct-read database like Realtime Database or Cloud Firestore. Since a read operation to this database does not benefit from a backend that can issue tokens and cache image URLs, it is not clear to me what the most performant way is to store these references.
I have come up with a few options and none of them are a clear winner.
Store a path like /images/foo.jpg to the database, and use Storage Client SDK to generate a tokenized path with storage.bucket().getDownloadURL("/images/foo.jpg").
Pros: Secure & simple.
Cons: Network call for every single image you want to display hurts performance considerably.
Store a tokenized path like https://firebasestorage.googleapis.com/v0/b/storage-bucket-823743.appspot.com/o/images%2Ffoo.jpg?alt=media&token=c6da1e33-f3ff-41e2-a6f0-bdb475a2f6d9 with a super long TTL.
Pros: No extra fetch on the client.
Cons: long string stored in expensive RTDB. What if that token is revoked by mistake? The database is now broken.
Store a path like /images/foo.jpg to the Database and use public storage rules. Reconstruct into a custom static URL like https://firebasestorage.googleapis.com/v0/b/storage-bucket-823743.appspot.com/o/images%2Ffoo.jpg?alt=media
Pros: Tiny database use, no extra client fetch, explicit public access, no token to lose.
Cons: URL encoding is super flaky, Storage could change their URL format and we'd be out of luck.
So, those are the options I've come up with, and there may be more. Any suggestions for how to solve this issue? The issue is unique because the Firebase databases don't have the benefit of a custom server to handle a token/caching layer to resolve this problem.
There is no single "best way" to store these paths. It all depends on your use-case, your preferences, and the context in which you're implementing it.
I typically use :
If I need access to the files to be secured, I store the image path (like in your #1), and then use the Firebase SDK to access the file.
If I don't need access to the files to be secured, I store the image path and the download URL. This way I can find the image easily based on the path, and use the download URL in non-secured clients.
The con's you mention for these are simply not affecting me. I'd recommend you take a similar approach, and report back when the problem actually occurs.
Haven't started development yet, but I just want to ask if there would be some security issues if I created a qr code that will directly download something from the firebase storage, will there be some authorization stuff needed? still choosing wether to store it from google drive or firebase storage(payment capacity reasons)
If you encode the download URL from Firebase Storage into the QR code, then anyone with the QR code can read the file. That is because the download URLs from Firebase Storage are publicly readable, but unguessable.
If you instead encode the path to the file into the QR code, then that file can only be access by a user that is signed in to Firebase and for whom the security rules you have configured allow read access to the file.
From what you described you're looking to use the first option with download URLs. It's hard to say what security issue you're asking about, but just be aware that in that case anyone with the QR code will know the download URL, and can thus read the file (or share that URL with others, so that they too can read the file). If that is not what you want, you'll need a more advanced scheme, which typically starts with being able to identify your users.
If I am storing something in Firebase and the key of that is something like -L1gMGVKaj-qU8O05eeT, is it safe to create public URLs like http://example.com/item/-L1gMGVKaj-qU8O05eeT?
Is it safe to distribute internal push keys to public, provided that proper database rules are in place?
There is no security issue in using push ids/keys in public URLs provided that your credentials (e.g. Server Keys or Service Accounts etc) are safe and not viewable.
However if you want that users should not be able to guess other push ids/keys then you should check this Answer
You can create your url using the keys generated by firebase on basis of timestamp. But it will not be user friendly. you can convert the key to unix timestamp and then use it for url. Look at this answer
Background:
Xamrin Forms Client App
Azure backend with Dot Net
Using Azure offline data sync
trying to use Azure offline File Sync
Related SO questions
there have been 2 more questions I asked here which are somewhat related
Getting a 404 while using Azure File Sync
Getting a 500 while using Azure File Sync
Solution
As stated above in the first link, I had to create a storage controller for the User entity to be able to successfully login even though I do not intend to use Files for Users.
As I work further in the app, I am still getting more 404 errors as I can see in fiddler. These are similar calls which are looking to access an API like below
GET /tables/{EntityName}/{Id}/MobileServiceFiles HTTP/1.1
My Question Now
Do I need a storage controller for every entity I have in my solution? may be every entity that inherits from EntityData?
Is there a way I can selectively tell the system which entities are going to work with files & have storage controllers only for them? Like, may be, marking them with some Attribute?
Reference
I am using this blog post to implement Azure File Sync in my app.
To answer my own query (and not the answer I wanted to hear) YES. We need a Storage controller for all entities, even if they don't have any files to be stored in Storage account. This is a limitation.
Found this info on comments of the original blog I was following (I wish I did it earlier), to quote the author
Donna Malayeri [donnam#MSFT] Chris • 2 months ago
It's a limitation of the current storage SDK that you can't specify which tables have files. See this GitHub issue: https://github.com/Azure/azure...
As a workaround, you have to make your own file sync trigger factory.
Here's a sample: https://github.com/azure-appse...
The reason the SDK calls Get/Delete for files in the storage
controller is because the server manages the mapping from record to
container or blob name. You wouldn't necessarily want to give the
client access to the blob account to access arbitrary files or
containers, for instance. In the case of delete, the server doesn't
even need to give out a SAS token with delete permissions, since it
can just authenticate the user and do the delete itself.
I'm learning to use OpenLayers and GeoWebCache.
My ultimate task is to use the Amazon S3 bucket as a storage cache location for GeoWebCache.
I can change this storage location to any local disk location (http://geowebcache.org/docs/1.5.1/configuration/layers/howto.html).
But don't know how to move to S3 bucket. Cos in geowebcache-core-context.xml I don't see a place to give credential for Amazon account.
Please suggest any solutions anyone have.
GeoWebCache uses geoserver to generate tiles to the filesystem and uses this filesystem structure of images, so I'm not sure if you can pull them from the amazon service.
If you found a way to retrieve the images with the help of a link (not filesystem request), you could use something like ashx handler (provided you use .net) to forward your request and add credentials to that request.