Serving authenticated static files from Amazon S3 - http

I have an application that allows users to upload contents to Amazon S3, and returns the link of the uploaded content.
I have been wondering how to allow only users that own the content to access it, and i got into http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html the authorization header.
A way to use it i thought is: generating a link to my application host for each content (e.g: from bucket.s3.amazonaws.com/29347524.jpg to -> myapp.com/image/154155.jpg) and serve it to user. When i receive a request i'll be checking if the user is authenticated in my application or not, and in successful match i'll allegate the authorization header to the request and forward it to amazon.
I would like not to download the content from amazon's server from my application's server and serve the content to the client. I think this is a useless waste of band.
Is there maybe any way to forward the request after adding some headers? So that the client is answered by Amazon when he requests the content but the request is made to my server and modified in some parts.
Do you know any other way to perform an authentication like this on Amazon's S3 content ? Any suggestion will be appreciated

I would look at the pre-signing facility in S3: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
Your application server can generate a time-bound URL as described there, and redirect the user using HTTP 302 with the corresponding Location header.
If you Google for "amazon s3 presign url", you'll find a few more resources: both blog posts and official Amazon docs.

Related

How to attach Authorization header when redirecting POST request?

We have a third party service that implemented single-sign-on on some route to it’s web-app.
In order to use this single-sign-on, we provided with a POST API, and we need to pass on that route some credentials- including an organization secret that we got from him (yes, we need to pass it in query params), and the user’s email address.
In order to not to expose credentials over the browser, we tried to mimic that request by creating our own backend endpoint, and return the same result as their enpoint (kind of a proxy) with redirection (status 307 with Location header) cause there API returns plain HTML.
It seems like when client send a post request with redirection he can’t add the authorization header (JWT) required by our backend to operate (backend return Authorization required). the request is been done to our server and the result is redirection to another server.
How can we bypass it? Or maybe we can secure it with different approach?
I know that the header is usually been removed for a good reason, who knows where I can be redirected to?
but can't I tell him somehow that I trust the redirection?
We tried to use phantom-form only to use from submit post. We tried to make our endpoint to be GET and making the redirection other way (react-router) but I think that natively js does not allow to attach Authorization header.
I thought it would be a common pattern, but I didn't find someone that talks about it exactly, since we are trying to query our backend and not some external redirection API.

Fortumo Web SDK processing

I am setting up Fortumo Web SDK payment for my website,
I am putting the url in "To which URL will your payment requests be forwarded to?"
I am using some DB related code here so that it would insert the code in DB and I could check it afterwards,
But when I test the payment it doesn't touch the GET URL and didn't send any request to this URL.
Need Support,
thanks
Finally, I am able to solve the issue, actually the main problem is that fortumo Web SDK works only with HTTPS links and send payment response as a GET Request to the specified link at fortumo configuration.
so no my link starts with https://multanwebtech.com/.......php

How to use nginx as a proxy for a private GCS bucket?

I have a GCS bucket which is private, and holds all of static media/image files that is used in my website.
Without making the bucket public, I need to have a mechanism for the users to access these resources.
GCS offers "Signed URLs with expiration time" to make these resources available which will be valid only for a specified time. Signed URL generation itself requires google libraries.
I use nginx as a proxy to the website. Does nginx support "plugging in custom logic to generate signed URLs for a resource request, and redirect the request to https://storage.googleapis.com" ?
I have read articles about URL Rewriting in nginx, but none of them solves this scenario which requires "unique URLs" for every request.
I have had the same need and I used a gcsproxy to do it: https://github.com/daichirata/gcsproxy
You may need to make some tries before having exactly what you want but it does the work.

OAuth + Google + Wordpress plugin

Background
I want to create a PHP application that eventually will be installed on a "countless" web servers.
The application is going to access the Google Drive associated with the web server's administrator Google account (it will basically write some files on user's cloud storage). So my PHP app will be authorized by the end-user to use its Google Drive storage. This is done (via the OAuth2 protocol) by connecting the Google OAuth2 service.
So basically I have to create a ClientID/Secret pair (on behalf of my Google Account) that is gonna be used to execute the authorization flow.
Google provides 3 authorization methods:
for web applications (web browsers over network)
for service account (my server to Google server)
for installed application (like Android, IPhone)
(1) is perhaps the best choice EXCEPT that I have to define a REDIRECT_URI where the authorization code will be sent. Because my APP will be installed on a "countless" different servers I don't know in advance the protocol, domain name and the path (also the URI) where the Google's response should be returned. If I would install this application only on 3 servers I could create upfront a ClientID/Secret pair for each of them. It's not the case.
(2) means to deploy my P12 private key with the PHP application and I don't feel comfortable with that!
(3) means to put the end-user to copy/paste an authorization token from a Google web page into my application web interface. I am trying to avoid doing that.
I already made it to work by using the method 1 when I know in advance the REDIRECT_URI. I also embedded the client_id/secret pair in the source code so the whole authorization process is user-friendly. But this is not going to work on a "countless" deployment scenario.
Questions
Which method and how should I use it in order to make the whole process safe for me (as developer) and for the client too (the web server administrator). Note that the authorization process should not involve the end-user to copy paste some codes. I want that step to be transparent/user-friendly for the end-user (no one likes copy-paste when it can be done automatically).
Should I embed my client_id/secret into the application or that's totally wrong? I suppose no end-user wants to go through the creation of its own ClientID in Google Developer Console, right? On the other hand why I would give my client_id/secret to an unknown end-user?
Final thoughts
I could create a proxy application on my (the developer) web server such that my PHP application (which is supposed to be deployed "everywhere") will send the authorization request to my proxy server (which has already its own client_id/secret) which in turn will redirect the call to the Google OAuth service which then REDIRECT_URI back the authorization code to my proxy and finally I will redirect back the response to the original sender (the PHP application). What do you think?
Some useful answers here and here or here.
#Edit: as I've already said earlier a proxy would be a solution. I've made it and it works. The same solutions I've received also from user pinoyyid. Thanks for your answer too.
A proxy is the only real option open to you. You can encode the originator URL in the "state" parameter, so that when the proxy receives the access token, it can call a webhook at the originator.
There are some contradictions in your question...
"The application is going to access the Google Drive associated with the web server's administrator Google account" and "So my PHP app will be authorized by the end-user to use its Google Drive storage." are mutually exclusive.
If the Drive storage belongs to the app, then the user isn't involved in any OAuth dialogue.
Could you edit your question to be clear who is the owner of the Drive storage as it greatly influences the OAuth flows.

How to prevent hotlinking of streaming content?

I have a directory with my media files and I need no to display them on other sites.
Server doesn't support .htaccess, because it uses nginx.
How can I enable hotlink protection for my files??
Thank you.
Easiest way would be to check for the Referer header in HTTP request. Basically if that header does not have URL from your site, then this could be hot linking.
This has following problems:
Referrer header can be forged -> hot linking works
All user agents do not necessarily send the Referrer header -> legitimate user might not get the content.
You could also set a cookie when user is browsing your site, and check for existence of that cookie when user is accessing the streaming content.
The details may be dated, but Igor gives an example of referrer mapping for image hotlink protection that might be useful here: http://nginx.org/pipermail/nginx/2007-June/001082.html
If you decide to go the referrer route.
If you are using memcached you could also store store client IP addresses for a time and only serve up your streaming media if an unexpired client IP is found in the cache. The client IP gets cached during normal browsing ensuring that the person viewing your streaming content has also recently been visiting your site.
On my hostgator site, they used nginx as a proxy to Apache(nginx+apache). maybe that will help you. Also if you have access to the logs, if you see a lot of traffic that way from a ip I would investigate, and if it points to a site, then block the other web server. Php's file_get_contents doesn't get stopped by htaccess or anything else I know besides blocking the ip.

Resources