I am in process of designing a SaaS application over PaaS (Google App Engine).
My SaaS will have two user interfaces:
Web Based
Mobile App based
Web based would be feature-rich whereas Mobile app would have essential and/or frequently used features.
Mobile app would invoke RESTful services to perform business logic.
This SaaS would target mainly individuals using Mobile Apps; however, there could a use-case wherein these individuals could form a group and operate as a company.
So with that in mind, I am considering two entities: Account (Tenant) and User.
I am considering having many-to-many relationship between these two entities as one user could be part of multiple Accounts (unlikely but can’t be ruled out) and of course, one account can have multiple users.
I would like to know the best practices for authentication under such scenario:
Should I use Google's provided Authentication or should I implement my own authentication? (I am still exploring OAuth and Google's authentication offering.)
I think, for web-based interface, username/password over SSL would suffice. But, not sure, can this be applied to mobile app?
Can I avoid a situation wherein I have to store credentials in mobile app?
Thanks in advance for any help you can provide on this.
A
Having just completed my first project using Google App Engine, I can say that I ran into alot of the questions that you have. I'll try to explain my approach to each point and also approach it from your perspective as well.
Authentication - Generally using Google's auth would be the easiest route, but you would still have to implement a custom adaptation in order to work with the "company"/"group" concept. Implement in the datastore/whatever database you prefer to use an entity called "Groups" which have a list of google users... this way users can belong to many groups.. then you just search by property (user) to get all groups they belong to. I implemented my own authentication system for unrelated reasons.
Google App Engine comes with SSL/HTTPS support for its own domains. You can add in your own custom domain with SSL support as well. You can use SSL through native apps or mobile web apps additionally. I simply used the native support that came with it.
Yes and no. You will always have to store the credentials somewhere. Maybe it wont be in your apps code/directly connected to your app (Google auth would be an example). But somewhere, on your phone, the credentials WILL reside. They may be encrypted/obfuscated, but they will be there. So either have your user enter them in everytime, or save them/use the ones provided by the phone. For myself, .NET provided a nice way of storing credentials in a secure fashion (non-plain-text) for each user's machine.
Related
I have spent 3 days researching this problem and cannot find a solution or similar use case that shows how to solve the problem, so any pointers would be greatly appreciated.
I am creating a web-app that uses Google Cloud Storage and Bigquery. A user registers on the web app and then can upload data to Cloud Storage and Big Query. Two users could be from the same company and therefore should be able to view the same data - i.e. Jack and Jill work for company A and if Jack uploads a massive dataset via this app, Jill should also be able to view it later.
Another scenario will be I have two completely separate clients with users using this web-app. If users from Company A upload data, users from Company B should not be able to view Company A's data, and vice versa. But users from the same company should be able to view the data within their company.
Currently, I have an app that works for a single company. This has a React front-end that uses Firebase for authentication. Once the user is logged in, they can use the app which sends off API calls to a Flask back-end that does some error checking and authentication checking and then fires off an API call to GCP. This uses a service account and the key is loaded as an environment variable in the environment in which the Flask app is running.
However, if Company B want to use the app now, both Company A and Company B will be able to see each other's data and visualize it through the app. In addition, they will be sharing a project (I would like to change this to allocate billing more easily to have each client have their own project).
I ultimately want to get this app onto Kubernetes and ensure that each company is independent of each other, however, do not want to have to have separate URL's for every company using the app. Also, I want to abstract GCP away from the client. I would prefer to authenticate a user based on their login credentials and then they will be given access to their GCP project (via my front-end) accordingly.
I thought about perhaps having separate service keys for each client and then storing the service key info in Firebase, while using the respective keys for API calls but not sure this is best practice. It is however the only strategy I can think of.
If anyone could provide some help or guidance it would be very much appreciated. This is my first GCP project and have not been able to find any answers on GCP, SO, Google Groups, Slack or Medium.
Thanks,
TJ
First if all, welcome on GCP! It's an awesome platform, very powerful and flexible. But not magic.
Indeed, the use case that you describe is specific to your business logic. GCP provides told for securing access for user and VM(through service account) but not for customer. Here you have to implement your own custom and authorisation logic, with a database (I don't recommend bigquery for website, the latency is too high) to list three users, the companies where they work, the blobs of each company...
Nothing is magic and your use case specific.
If you want to discuss more about which component to use and to start, no problem. Let a comment.
I've been thinking about this quite a while and it's bugging my head off, lets say we have a website a mobile app and a database.
Usually when we develop our websites we pretend to store our database credentials in a configuration file and connect the website directly to the database without using a multi-tier architecture, but when it comes to a mobile application such Android or iOS this applications can be engineer reversed meaning that there's a risk of exposing your database credentials.
So I started thinking about this multi-tier architecture and kind of thinking about how Facebook and other social network do their job, they usually make an API and use a lot of HTTP Requests.
Usually social networks APIs have a app_id and a secret_key, this secret key would be used to increase the safety of the application but I'm thinking about how could I store these keys inside my application since I would go back to the begining of my discussion, if I was to use Java I could use the Java Preference Class but that isn't safe either has I saw in this question, plus I would need to make sure my HTTP Requests are CSRF safe.
So, how could I store these keys inside my app? What's the best way to do it, since hard-codding it's out of the question.
You should always require users to log in - never store credentials or private keys in an app you'll be distributing. At the very least, don't store them unless they're specific to the user who has chosen to store them after being validated.
The basic idea is that the user should have to be authenticated in some manner, and how you do that is really too broad to cover in a SO answer. The basic structure should be:
User asks to authenticate at your service and is presented with a challenge
User responds to that challenge (by giving a password or an authentication token from a trusted identity provider).
Service has credentials to access the database, and only allows authenticated users to do so.
There are entire services out there built around providing this kind of thing, particularly for mobile apps.
You might store the users own credentials on the device, and if so it should be encrypted (but you're right, a malicious app could potentially pick them up).
Bottom line: never distribute hard coded access to a database directly.
I have tried searching the info regarding applications on GAE within same domain talking to each other but so far I don't have any luck. There was a post here but I don't know if that answer is correct.
You could also run the two different "apps" as different versions of the same appid. Then they share the datastore. Also, urlfetch.fetch() calls to paths of the same app are treated specially, they are faster and don't require authentication (they count as if they are logged in as admin).
I believe you will be best served by exposing a REST API for both your applications, so that they can read/write information as needed.
For e.g. If one of your apps is an Invoicing App and the other app needs only read access to Invoices, you can expose an API in the Invoice App for:
searching invoices by some filter
providing the Invoice detail, given an Invoice ID
Exposing an API will keep the applications loosely coupled with each other and will allow you to enhance the API as more requirements emerge. In the future, you can even have other clients like a mobile app access the API.
Looking at the Google App Engine API, it seems that despite all its great features, the User API is extremely limiting. It seems you can only authenticate people who have a Google account, or use an OpenID account, or via some OAuth kung fu (handshaking with a Facebook account etc).
This appears to be a major stumbling block for anyone who wants a proprietary user base by creating user accounts within the application. In short, I don't want my users to have to use or create a Google account to access my app.
Has anyone else come across this limitation and has it been a deal breaker for using the GAE? Am I missing something? It is possible to deploy my own Spring based security etc within the app and use my own User API? Comments on this issue greatly appreciated. Thanks.
You're free to completely ignore the Users API and implement your own authentication system, as you would in any other hosting environment. Nothing about App Engine prevents you from doing so.
The Users API is just there as a convenience, in case you'd like to spare yourself the effort of re-implementing everything, and spare your users the inconvenience of filling out another sign up form and remembering another set of credentials.
You can always implement your own user management system.
In my application I have used spring-security for this purpose. spring security 3.0.1 works perfectly fine with app engine 1.3.5. There may occur some issues integrating other versions of both. I found below links extremely useful :
http://www.google-app-engine.com/blog/post/Spring-security-fix-for-google-app-engine.aspx.
http://www.dotnetguru2.org/bmarchesson/index.php?p=1100
http://groups.google.com/group/google-appengine-java/browse_thread/thread/964e7f5e42840d9c
I am still trying to wrap my mind around the workings of OAuth/OpenID, as such...
I am developing an "installed app" that will run on computers and iPhone. A given user may install the client app on multiple machines, and all of the user's installed clients will synchronize via a centralized Google App Engine service. The GAE service will also allow multiple users to collaborate on the data produced by the installed app, via a web app.
I don't want to roll my own authentication system, for my own ease and also to spare users from yet another set of credentials. As such I was initially thinking of using Google's clientlogin service, but then I thought OAuth/OpenID would be better because it would allow users to use not just Google credentials but also credentials from the other OpenID providers. Also, avoiding asking the user for a login/password seems more secure.
My question is... I'm not sure if this is the right use case for OAuth/OpenID. I am not accessing data from any other service, I am just looking for an authentication solution. Also, how difficult is this scenario to accomplish using Google App Engine (java)?
Any advice and/or starting points would be much appreciated!
My question is... I'm not sure if this is the right use case for OAuth/OpenID.
The "use case" for oAuth is: App X requires access to App Y. App X "asks" permission for access to App Y through your credentials. App X received an "authorized access token".
In your case, assuming I understood correctly, you could have the App on GAE implement an OpenID consumer and have your mobile app access the GAE app through oAuth.
In other words, your approach seems like a sensible one.