Use Symfony to authenticate users for external service - angularjs

I've been googling the entire afternoon and I'm still not able to figure out what's the best solution to implement the following:
We have build a webapp in AngularJS that consumes interacts with REST API build using Symfony. The app allows users to register, login and do stuff. Now, these users need to upload very big files (>60GB) into their personal folders. A separate VM have been setup for this purpose (data server), located in the same VLAN as the frontend, backend and the MySQL db serving the data. The data upload will be done using either HTTP (using JQuery File Upload plugin) or an FTP client.
I'd like the users to authenticate into the data server (both via FTP or HTTP) using the credentials they already have for the app. For the FTP case, I'll use PureFTP as FTP server, which validates user/pass directly from the MySQL. As far as I know, this is the most convenient solution, but criticism is accepted.
For the HTTP upload, we could proceed in a similar way: POST user/pass, validate against DB and return true/false. Since all the communication will happen within the VLAN, security issues are less problematic. Nonetheless, I believe much more sophisticated solutions have already been developed.
My first thought was to build an OAuth server on Symfony and then authenticate the uploader (and future services) with their respective clients. Is this a right approach or is this a too complicated solution?
Alternatively, a service in the dataserver could validate user's credentials sent by the client against the REST API, receive a JWT and generate a new session for that particular client to list and update files on a particular folder. I'm not sure how to build this middleware though, do I need another Symfony instance or a simple PHP script will do the trick?
Please do not hesitate to share any thought you have on this. Any point of view will be much appreciated.
Thanks a lot

Related

How to prevent JSON data from being Tampered in a REST request?

The following is the architecture of my Web application.
Web UI(Angular JS) running on nginx
Back-end data access layer (Java App) running on glassfish app server
My question is, how can I prevent a valid user from tampering or manipulating the REST service JSON request using some proxy tool.
One thing that I thought of was to encrypt the JSON but this will still expose the public key and the source code of how to encrypt it since its done on client side scripting. Is there a better way of doing secured JSON request?
P.S: I'm not talking about "Man in the middle Attack". This is not related to session hijacking. This is about a valid session user tampering the POST request using tampering tools.
You can't.
Anything that runs on client-side is exposed. Almost everything there can be tampered.
So your best bet is that you have a strong server-side validation before you process the data from the client.

Access Google Cloud Storage from web application, always 403

I am work on a web application as an interface with Google Cloud Storage(GCS).
I am using a backend service to retrieve the list of files I stored on GCS and their URL with the JSON API and return that to my web application. However, I was not really able to load the files through those URL, which always came back with 403 forbidden.
I am not sure how GCS authentication work behind the scene and whether it is possible to directly grant access to web application. I am not sure how could I attach application authentication information via http request. What I know is I can do that via the backend service but for the reason of simplicity I wonder if it is possible to get around with that. One of the thing I tried is adding the web application domain(which will be sent via referrer in http request) into ACL to that bucket, which doesn't work at all.
And thanks to what #Brandon pointed out below. I am ok to grant anyone whoever have access to the application to view the content of the GCS since it is an internal app and I have already checked their authentication when I first serve the web application.
====
Solution
I ended up using the signedUrl that expire in 5 minutes and I highly recommend interact with gcs using gcloud (Their python document is really good). Thanks again for the thorough answer!
You have a user on a web browser who wants to download an object that only your application's service account has read access for. You have a few options:
Expand access: make these object publicly readable. Probably not the best choice if this info is sensitive, but if it's not, this is the easiest solution.
Give your app's credentials to the user so that they can authenticate as your app. This is a REALLY bad idea, and I probably shouldn't even list it here.
When a user wants to download a file, have them ask your app for it, and then have your app fetch the file and stream its contents to the user. This is the easiest solution for the client-side code, but it makes your app responsible for streaming file contents, which isn't really great.
When a user wants to download a file, have them ask your app for permission, and reply to them with some sort of token they can use to fetch the data directly from GCS.
#4 is what you want. Your users will ask your app for a file, your app will decide whether they are allowed to access that file via whatever you're doing (passwords? IP checks? Cookies? Whatever.) Then, your app will respond with a URL the user can use to fetch the file directly from GCS.
This URL is called a "signed URL." Your app uses its own private key to add a signature to a URL that indicates which object may be downloaded by the bearer and for long the URL is valid. The procedure for signing URLs is somewhat tricky, but fortunately the gcloud storage libraries have helper functions that can generate them.

Do you really need a server for AngularJS app?

I want to deploy my AngularJS app which access RESTful web-services onto an aws and I am wondering if I really need a server to serve my AngularJS files.
I can server them as static files or use something like NodeJS but do I really need one?
What are the advantages/dis-advantages of using a server in this scenario?
If your app is small, it's really not a problem if you only access to an API.
But if you want to login via other services where you have for example a public and secret token it's better to work with a server who use cache this datas from your users (maybe it's what your aws is doing).
If you want to access RESTFull Web Services from AWS, you need to put your angularjs files in a server.
The server will give access to resources, if the request is from http protocol. It will deny the request to serve if the protocol is file.

Security in Extjs 4

I am new to Extjs. My question is if I have to communicate to Server and get records from database. How can I secure my Ajax or rest calls as every communication to server is done via ajax or Rest. Is SSL is the only way to secure our ajax/ rest calls to server?
It depends very much on the nature of your application, but HTTPS is best practice when transferring any sensitive information to a remote web server such as a password or session token. OAuth 1 or 2 is probably the way to go.
This link describes different options https://stormpath.com/blog/secure-your-rest-api-right-way/
Also, to save yourself time, you may want to consider using a platform like DreamFactory to provide a REST API interface for your SQL/No-SQL database. This provides user session management and saves you the extra effort of coding your own REST API.

Express/Passport local authentication multiple servers

I am building a real time web application with angular js, express js and passport js.
The passport authentication is working fine on the main server. I have written a second logging server also in express js and want to use this to simply receive http POST requests from an angular js service. This will enable client side exceptions/errors to be recorded and available for debugging purposes etc. I don't want to introduce a dependency on logging in the main server so to have this logically separated.
I am thinking about introducing a redis store for passport/express sessions so that the logging server is also subject to authentication and sessions can be shared across the two servers. I am not sure how to implement this session sharing though.
In this scenario what is the best practice is for authenticating across the two servers - I don't want the user to have to log in twice.
You nailed it down. redis store yes. There's no need for manual implementation. Have both servers use same instance of redis server (i.e. cloud redis, installed locally on only one machine etc). express sessions have the ability to use redis store (take a look at connect-redis package). Sharing is accomplished automatically since both stacks will communicate with same redis store.
The way it works in details, when the user is auth the connect.sid cookie gets written to the browser. then subsequent requests (i.e. to second server) will transmit this cookie. second server sees the SID and looks it up and finds it and retrieves the same session from redis.
It's hands off implementation.

Resources