Get logged in user information in SAML Single Sign On google app engine - google-app-engine

I am trying to get the user who is logged in via. SAML Single Sign On.
I have already implemented SAML Single Sign On and it works.
The code I use for programmatic login is :
apps = gdata.apps.service.AppsService(email=username, domain=domain, password=password)
apps.ProgrammaticLogin()
logging.info("current user %s", users.get_current_user())
//Redirect to a Google mail page.
But users.get_current_user() returns None always even though correct username and password is provided. I have crosschecked it by redirecting the page to Google Mail page and it successfully redirects.
I have googled this issue for hours now nothing goes the right way.
Can anyone please guide me what I am doing wrong ?

There are three different things going on here, I just want to make sure are clear for my suggested answer to make sense:
Google App Engine users service: You, as the developer, delegate authentication and authorization responsibility to Google Accounts (or the selected OpenID provider). Google will act as the Identity Provider and you'll act as the Service Provider.
SAML single sign on: Google delegates to you the authentication and authorization responsibility, you'll act as the Identity Provider and Google will act as the Service Provider. You'll be using SAML SSO every time you try to login any Google service using you Google Apps account, that includes Google App Engine applications using the users service.
ClientLogin: It is one of the methods for authenticating to use a Google API by giving username and password. It's deprecated, it's hard to maintain and insecure since you are hard coding the credentials and the app could have access to everything. I'd recommend switching to OAuth instead. In the first two lines of code You are initializing the Google Apps provisioning API with gdata.apps.service.AppsService, if you are not going to retrieve or create users/groups/alias is useless to do that. If you are I'd also recommend switching to the Directory API part of the new AdminSDK
For your particular case I'd suggest checking if there is a current user logged in, if not redirect to the login URL using the GAE users service.
user = users.get_current_user()
if user:
logging.info("current user %s", user.email())
else:
return redirect(users.create_login_url(request.url))
In case you always require that the user is logged in you better set the handler as login: required
The user will be redirected to the SAML SSO page to log in to his Google Account in order to access the GAE app.

Related

How to Authenticate user, password with Google App Engine + Java?

I need to authenticate user email and password with Google. I am using App Engine + Java environment. Is there any provision in Google APIs ?
currently i am using
ContactService client = new ContactService ("yourCompany-yourAppName-v1");
client.setUserCredentials("user#example.com", "pa$$word");
I need to replace this Google APIs. I need to authenticate user with Google not application.
Please suggest me how can i do this.
In your last comment you say that the google username and password is entered in the client and validated in the server. That is NOT possible, google has deprecated the ability of an app to capture the password and thats excellent.
The only way to do this is with oauth2, BUT addionally you need to pass a special parameter &max_auth_age=0.
At this point this question is basically a duplicate of this: No prompt for re-authentication with OAUth2. Why and how to force it? however I didnt mark duplicate because yours is a different situation.
Explaining oauth in detail is not part of this answer as its explained well in the official documentation and many guides. Do not use the built-in appengine userService. Instead configure appengine pages so they are all public and on top implement oauth2, for example using the existing google+ javascript signin libraries (thou not sure if those let you set the max_auth_age parameter. If not, you need to roll your own oauth2 "client side 3-legged" flow. In that flow, the client will see the google login page every time, and after the client-side flow finishes, the client will end up with an access token which is what it sends to the server to validate that the user entered the correct username and password. If you include the correct scope (userinfo.email scope) then the server can use that access token to ask google the username that generated the token, thus you have validated that the client did login to google and you know their email.
But you will NOT receive the password. Just enough info to authenticate the user.
The question isn't very clear, I'll try to respond in two way.
1) Authenticate users on appengine with custom username and password.
To do that you need the "classic" way, I suggest you to use a framework like Spring with his module "spring-security", take a look at this sample.
2) Authenticate users on appengine with Google Account.
This is the best way I think, you only need to follow this guide.

OAuth2 in Go with Google App Engine

I'm looking into using OAuth2 with Go in Google App Engine.
Here is a link with an example:
https://developers.google.com/appengine/docs/go/users/#Go_OAuth_in_Go
But this remark isn't clear to me:
Note that using OAuth to identify your users is completely orthogonal to the
standard user authentication modes. For example, pages marked with
login: required or login: admin will refuse to load if the user is
only authenticated via OAuth.
Does this mean I can't use the standaard authentication mode with OAuth?
Can I use other providers like Facebook with the user package?
Or is it better to use this package instead of the default user package?
https://code.google.com/p/goauth2/
Are there disadvantages to using this?
(I only need it for authentication)
This just means that the app.yaml/module.yaml key "login" won't consider users who have authenticated via OAuth to be authenticated and will deny them access to that resource.
For example, if you have created a page at /admin/ and you want GAE to enforce that only people who have authenticated can access that page, then you need to ensure that they have authenticated using a google account, not an OAuth login. Anyone accessing that after they have logged in using OAuth will still appear unauthenticated to GAE.
All that this means is that if you have pages you only want authenticated people to see and you want to support OAuth as a valid authentication method, then you need to not have the "login" key set for those resources in the .yaml file. Then it's up to you to enforce that they have been logged in before allowing them access to that resource. GAE can't help you out in that case.

Can we specify a domain when redirect user to sign in with oauth2 in appengine?

When we were using the UserService api, we can specify a domain when generate auth url. But when we switch to oauth2 (with google client library for java API), we are using AuthorizationCodeFlow.newAuthorizationUrl() to generate auth url, however we cannot specify any domain, so for example, if one customer already logged in with his gmail account in some other google sites, but he want to sign in our app with another google apps account, he has to logout from google site since the authFlow always get the gmail account credential, we don't have a way to force him log in to a specific domain. We didn't have this issue when using UserService api.
Just want to know if there is any solution for this.
If you attach "hd=$domain" to the OAuth2 authorization request query parameters it will prompt user to login to that domain (if user not yet logged in) and/or optimize selection of the user's account in that domain.

Custom domain app requesting permission to access Google Account

I refer here to that page you are redirected after you login to GAE app with your google account, which asks your permission to access your google account.
Put this toghether with custom domain and https and you get my problem.
Sorry for the lengthiness. I searched everywhere. Didn't find anything. Not sure it is an OAuth issue (think not).
My configuration:
developed myapp.appspot.com
configured custom domain myapp.mydomain.com to point to myapp
myapp is making use of GAE login service
need for https posts from custom domain (!), solved as follows:
page is loaded in HTTP from http://myapp.mydomain.com
some submit HTTPS URLs are hardcoded in the page, as https://myapp.appspot.com/someservice
same domain policy resolved server side by means of http headers
GAE login service applies both to http://myapp.mydomain.com handler AND https://myapp.appspot.com/someservice handler
The workflow is:
user not yet authenticated
user browse http://myapp.mydomain.com (not ssl)
user is redirected to google account login page
user logins
user is redirected to the abovementioned page: myapp is requesting permission to access user's google account
user grants his permission
user is in - OK
Now comes the problem:
user makes a submit to https://myapp.appspot.com/someservice (so that data is ssl transmitted), which is loginrequired decorated
login is ok, user is not again redirected to the login page,
I think this is because the google login is cross application (the same should appen if the user was already logged in into gmail, to say)
but now https://myapp.appspot.com/ is again requesting permission to access user's google account - and this is the problem
The user is prompted TWICE to grant permission to myapp to access his account:
once when he browse to http://myapp.mydomain.com
and another one when he submits data to https://myapp.appspot.com/someservice
My user doesn't like it and me too !!!
I suspect this is because the user answer (Allow or No Thanks) is saved server side with respect to the URL of the app
and not with respect to some other unique id of the app.
But I have no idea how to solve it or at least work it around.
Thank you for your patience in reading up to here.
Any help would be appreciated.
The cookie that is issued for the user's session is per-domain and per-protocol. As a result, the same session won't work on the appspot app and on your custom domain. This isn't an App Engine limitation - it's simply how HTTP works.
The best solution, currently, is to put the form itself on HTTPS as well (which is in general a good idea anyway).

federated login Vs. oauth on google app engine

i would like to provide a third party user authentication on my app engine app.
the federated login option on appengine is not exactly what I'm looking for and i can't see endpoints
what i want is authenticating users via openid like its done here on stackoverflow.
the first time a user has to authorize the app and the subsequent times it will only need to be logged in or log in again on the third party app and then redirected to my app.
my app is written in python and im using tornado web as a framework. i've seen that tornado has its own auth module i want to check out but i wanted to ask for suggestions before jumping into code.
basically i would like users to be able to log in via facebook, twitter and google.
the facebook authentication seems not to be that hard on graph.facebook.com but its not easy to test
authenticating via twitter looks more difficult to me and i can't find any clear examples.
i would love to hear your experiences/suggestions about it.
What you describe is exactly how federated login with OpenId works on App Engine. Whether or not users get prompted for authorization after the first login is up to the OpenId provider, not the consumer.
Facebook login doesn't use OpenID, and you'd need to implement that yourself, in conjunction with a sessions library to keep track of logged in Facebook users.

Resources