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.
Related
My goal is to run a google app engine application with the minimal amount of access to resources it needs. In my case the application will access the datastorage in the project (this is the golang example tutorial using the source code git checkout origin/part4-usingdatastore from https://github.com/GoogleCloudPlatform/appengine-guestbook-go.git)
I did the following
Create a new project, foobarproject3
Created a new app in the project (using golang)
In the project IAM/IAM noticed the
foobarproject3#appspot.gserviceaccount.com, assumed this is the service account, so changed it's role to just BigQuery User. Notice that no Datastorage roles are configured (The UI forces me to provide access to something so I chose BQ)
Followed the tutorial instructions for the using datastore golang app (guestbook application)and deployed the app.
Opened the link to my app: https://foobarproject3.appspot.com/ It failed (this is great, this is what I expected, since the service account does not give the app permissions to read/write datastorage)
Refreshed https://foobarproject3.appspot.com/ and it started to work
There is something basic that I'm not understanding about service account from app engine. Isn't the app engine using these service account to access project resources? Why is the app getting access to datastorage when the service account does not have a policy that would allow access to datastorage?
"My goal is to run a google app engine application with the minimal amount of access to resources it needs."
This is dicey to unpack without more context. What is it that you're trying to achieve that goes beyond App Engine's default behavior?
My experience is that if one starts changing roles without understanding the basics, things go sideways (or South, or West, or Pear-shaped, depending on where you are). So I suspect you shot yourself in the foot in your third bullet.
When you access your app from the browser you are using your own user credentials, not the app's service account. And your user credentials might be exactly the app owner/admin ones, if you created the app using those credentials. See, for example, app.yaml handler login: admin option not effective on standard env python GAE app?
Make sure you log out from the app, or try accessing the app from an incognito browser window or by using a dumb(er) utility to prevent accidental/undesired credential leaking.
The app's service account is for your app to identify itself when it's interacting with other services/apps. From Understanding Service Accounts:
A service account is a special type of Google account that belongs to
your application or a virtual machine (VM), instead of to an
individual end user. Your application assumes the identity of the
service account to call Google APIs, so that the users aren't
directly involved. A service account can have zero or more pairs of
service account keys, which are used to authenticate to Google.
I build Android app link to Google Cloud Storage. I want to allow access to GCS to my android app ONLY.
Google offers three solutions to securely connect to GCS:
Oauth 2.0 (So with google account)
Cookie-base Account (With google account too)
Service Account Authentication (With private Key, but locally installed on Android App: Very Bad if someone decompile my .apk)
Source: https://developers.google.com/storage/docs/authentication?hl=FR
Is there any other solution to connect securely over GCS ? I would like to connect on GCS to this way (Restrict to Android client ID: SHA1 to your .apk) : https://developers.google.com/appengine/docs/java/endpoints/auth
It is possible with GCS ? Should I use Blobstore to do that ?
Thanks in advance
This is something of a fundamental problem with computing. You can never completely trust that an application running on hardware that is under the total control of an unknown third party has not been somehow tampered with. There are many, many techniques to make tampering much more difficult, but remote systems will never be completely secure. There are several ways to verify that a user has a particular Google account, but you can't easily trust with certainty that a certain app is exactly your app.
That said, there are plenty of ways to design a secure application without trusting the client. What does your app need to be authorized to do? Upload objects? Download secure objects? Is there something bad that a user masquerading as your application could do?
I think you can use 1) to authenticate the information. The app will forward the authentication request to your server (with your own app login token), and when the user is validated by your own services, then the app will receive the oauth token to send to gcloud and receive the desired file.
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.
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
We are starting a very large web based service project. We are trying to decide what hosting environment to use. We would really like to use Google App Engine for scalability reasons and to eliminate the need to deal with servers ourselves.
Secure logins/registrations is very important to us, as well as using our own domain. Our target audience is not very computer savvy. For this reason, we don't want to have the users have to sign up with OpenID as this can't be done within our site. We also do not want to force our customers to sign up with Google.
As far as I can see, I am out of luck. I am hoping to have a definite answer to this question. Can I have an encrypted login to our site accessed via our domain, without having to send the customers to another site for the login (OpenID/Google).
Thanks.
The hardest part is getting around the cookie issue. While you can do secure and custom logins against https://yourdomain.appspot.com, you cannot set a cookie there that will work on http://yourdomain.com.
Here is what I propose:
When you need to log the user in, send them to https://yourdomain.appspot.com. If they enter the credentials properly, create a one-time token and place it either in the datastore or in memcache. Give it a lifetime of a few seconds.
Then redirect the user back to http://yourdomain.com/authenticate?token=mytoken (obviously substitute the names as appropriate), check to make sure that the token is valid and has not expired, and if all is clear, set the appropriate cookies and expire the token.
I think that'd work just fine. Hope it helps!
As of June 27, 2012, App Engine supports SSL for custom domains.
http://googleappengine.blogspot.com/2012/06/google-app-engine-170-released-at.html
There is nothing stopping you from creating your own authentication/registration mechanism with Google App Engine. The only problem is that Google App Engine currently only supports HTTPS via https://yourid.appspot.com and not your Google Apps Domain (i.e. https://www.foobar.com). However, this is on the product roadmap for future support (SSL for third-party domains). Note, also on the product roadmap is built-in support for OAuth & OpenID.
Update: Another option may be to use a proxy server (like Apache with mod_proxy) and map your domain to the proxy server and then the proxy server can proxy the HTTP and HTTPS requests to Google App Engine. The requests could be proxied to the appspot.com domain behind the scenes. I haven't actually done this, but I believe it should work. However, this would give you a single point of failure at the proxy server which basically defeats the purpose of Google App Engine's high-availability and scalability. This would definitely just be a short-term solution until Google supports SSL for third-party domains or OpenID.
Depending on whether your threat model can accept a non-encrypted link on the "last hop" to GAE, you can use a proxy to handle SSL from the browser. Here's a HOWTO I wrote up on using CloudFlare to get always-on SSL:
http://blorn.com/post/20185054195/ssl-for-your-domain-on-google-app-engine
This isn't structurally any different than the way SSL from Google will work, it's just that Google-provided SSL will terminate within G's network rather than just outside it. If you're trying to protect against Firesheep, CloudFlare (or any other SSL proxy) will do fine. If you're worried about snoops on the trunk connection between CF and Google, you may want a more sophisticated solution.