How to make AccountManager (authtoken) and OpenID work together (without AppEngine)?
Asked Answered
C

1

15

I am making an Android app which should be able to get data from a web service (which is not part of GAE). Users are able to log in to web service through their browser by using OpenId (only Google accounts are allowed).

AccountManager can give me authtoken. I could save this authtoken on my server, together with user's google account name (email) and then use this account name to connect his openid login with app registration.

But this does not solve anything because I have no way to verify this token against user's OpenID information... Or do I? I thought I could use user's authtoken to "somehow" link his android account to the web account.

This looks more and more like a wrong way to handle this but I do not want to save users Google's username/password in SharedPreferences and use these data for login.

Any creative ideas? Thanks

Centralia answered 8/6, 2011 at 8:38 Comment(3)
nobody with an idea? I read a lot of questions about some related topics but I found no solution.Centralia
We have exactly the same question. From what we have tried, it seems the authToken we can get from the AccountManager can only be used to gain permissions for a specific google API using OAuth - not authenticate the user using openIDSculpturesque
i would also love to know, i need to do the same thingRuwenzori
V
3

I solved this exact issue for my app Push Actions - http://www.pushactions.com. For my solution, I did end up using GAE, but only to authenticate the token. The actual Push Actions app is hosted on Heroku. Here's my flow:

  1. Android app generates GAE token then posts the token & the account's email address to Push Actions running on Heroku
  2. Push Actions posts the token to my service running on GAE
  3. The GAE service takes the token, determines if it is valid, and returns the email address it is valid for
  4. Push Actions compares the email address returned by GAE with the email address from the android app, if they match, the token is valid for that email address. This means the token can be safely associated with the google user's openid email address.

As far as I know, this is the ONLY way to verify if a token generated by AccountManager is valid. True, it does require the use of GAE, but only for one small piece of your overall app. My GAE service ended up being like 1 class and a few lines of code, so it isn't much. You can think of the GAE piece as a service provided by google for authenticating tokens.

Here is the code for my GAE service:

package com.pushactions;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

@SuppressWarnings("serial")
public class PushActionsAuthServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(HttpServlet.class.getName());

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if (user != null) {
            req.setAttribute("user", user);
            try {
                req.getRequestDispatcher("/logged_in.jsp").forward(req, resp);
            } catch (ServletException e) {
                log.severe("Couldn't redirect to logged_in.jsp");
            }
        } else {
            try {
                req.getRequestDispatcher("/logged_out.jsp").forward(req, resp);
            } catch (ServletException e) {
                log.severe("Couldn't redirect to logged_out.jsp");
            }
        }
    }
}

logged_in.jsp:

<%@ page import="com.google.appengine.api.users.User" %>
<% User user = (User)request.getAttribute("user"); %>
<?xml version="1.0" encoding="UTF-8"?>
<result>
<status>ok</status>
<user_name><%= user.getEmail() %></user_name>
</result>

logged_out.jsp:

<%@ page import="com.google.appengine.api.users.User" %>
<% User user = (User)request.getAttribute("user"); %>
<?xml version="1.0" encoding="UTF-8"?>
<result>
<status>error</status>
<message>not logged in</message>
</result>
Velasquez answered 7/7, 2011 at 19:2 Comment(4)
I'm telling you guys, this is the answer :) Imagine if google provided a service that authenticated tokens. All you had to do was post the token generated by Android to the service and Google would respond with whether or not the token was valid. Does that sound suitable? Well that is exactly what my answer provides.Velasquez
awesome that looks like just what i need. can you tell me how you pass the token and email to GAE (to your PushActionsAuthServlet). i can't tell from your code. thanks so much!Ruwenzori
Hey dweebo, I just do an http get to "MYAPP.appspot.com/_ah/login?auth=GAE_TOKEN&continue=https://…" http post might work as well, haven't testedVelasquez
I've done just the same thing you did. I created a python GAE app to receive the authentication information and return the email of the user. One thing that must be checked is that some users have upper case characters in their email addresses so remember to only compare the emails after using some function to make all characters lower case.Itchy

© 2022 - 2024 — McMap. All rights reserved.