Code in reference to: http://groups.google.com/group/google-appengine-java/browse_thread/thread/47306a917b8e1628
I'm not getting back the ACSID Cookie. The comments in the Servlet Code below explain everything. I hope this helps someone else getting started because I had a ton of sifting to get to this point. package com.google.lavards; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import javax.jdo.PersistenceManager; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.*; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.net.*; import javax.jdo.Query; 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 MyGoogleAppServlet extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { try { /* * Example Request from a browser: * http://localhost:8080/api/v1/merchant?merchant_id=someu...@mygoogleapp.com&merchant_key=TheirPassword * * Goal: * 1. to have user != null and to access getCurrentUser()'s email * * Steps: * 1. Use merchant_id and merchant_key to login to the HOSTED Google account and get an authentication Key * Http POST to * https://www.google.com/accounts/ClientLogin?accountType=HOSTED&service=ah&email=someu...@mygoogleapp.com&Passwd=TheirPassword&source=MyGoogleApp * * 2. Use the authentication Key from Step 2. to get an ACSID cookie from Google * Http GET to * http://mygoogleapp.appspot.com/_ah/login?auth=TheResultingAuthKeyFromStep1 * * 3. Use the resulting ACSID cookie for the initial request Redirect to * (strip off merchant_id and merchant_key) with Http Header 'Set- Cookie' = ResultingCookieFromStep2 * http://localhost:8080/api/v1/merchant * * Problem: * 1. The ACSID cookie is never present, however a PREF * Cookie is?? 2. Can't get user != null, thus I can't get their email * * Things that work: * 1. I receive the Auth token from Step 1 Http status 200 (ok) * 2. I receive a Http status 204 (no content) for step 2 * * Future Goals: * 1. Save the resulting cookie in the session and reuse it for future requests over the same session * * Comments: * 1. I know that the Google app documentation on ClientLogin says to use the Auth token * for future requests, but from all the examples that exclaim their code is working they had * to use the Auth token to get the ACSID Cookie, then they used that Cookie for future requests. * 2. I havn't received much help on this issue. I really hope posting this code will help others * suffering from this same problem. I feel like I could have been working on things more * interesting then basic Authentication problems. Maybe Google will write a good example * of proper app Engine Authentication at some point and include all of the normal * path's that are NOT supports. IE. using the Authentication Http header, and simply * getting the Auth token and passing it in future requests. */ UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); if (user == null) { // need to authenticate the user // we don't have our GoogleLogin auth token // fetch the auth token from google String loginPath = "https://www.google.com/accounts/ClientLogin"; String merchantId = getParameterValueByName(req, "merchant_id"); String merchantKey = getParameterValueByName(req, "merchant_key"); HttpURLConnection connection = null; String authKey = null; if (merchantId == null || merchantKey == null) { resp.sendError(403, "[InvalidMerchantException]"); return; } loginPath += "? accountType=HOSTED&service=ah&source=MyGoogleApp&Email=" + URLEncoder.encode(merchantId, "UTF-8") + "@lava-rds.com&Passwd=" + URLEncoder.encode(merchantKey, "UTF-8"); try { URL authUrl = new URL(loginPath); connection = (HttpURLConnection) authUrl.openConnection(); connection.setUseCaches(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-www- form-urlencoded"); connection.connect(); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader (connection.getInputStream())); String line; while ((line = reader.readLine()) != null) { if (line.contains("Auth=")) { authKey = line.replaceFirst("Auth=", ""); } } reader.close(); } else { resp.sendError(HttpURLConnection.HTTP_FORBIDDEN, "[InvalidMerchantException]"); return; } } catch (MalformedURLException e) { resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "[MalformedURLException]"); return; } catch (IOException e) { resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "[IOException]"); return; } finally { if (connection != null) { connection.disconnect(); } } // set the google cookie using the auth token if (authKey == null) { resp.sendError(HttpURLConnection.HTTP_FORBIDDEN, "[InvalidMerchantException]"); return; } String cookieHeader = null; try { String cookiePath = "http://MyGoogleApp.appspot.com/_ah/login? auth=" + URLEncoder.encode(authKey, "UTF-8"); URL cookieUrl = new URL(cookiePath); connection = (HttpURLConnection) cookieUrl.openConnection(); connection.setUseCaches(false); connection.setRequestMethod("GET"); connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_NO_CONTENT) { Map<String, List<String>> cookies = connection.getHeaderFields (); for (String cookie : cookies.keySet()) { if (cookie.equalsIgnoreCase("Set-Cookie")) { //For some reason the cookie PREF is present, but I noticed it was //cutting off the end of the cookie so I grabbed both 'bites' and //combined them //This is also where I expect to find the ACSID Cookie, never present List<String> bites = cookies.get(cookie); for (String bite : bites) { if (cookieHeader == null) { cookieHeader = bite; } else { cookieHeader += bite; } } } } } else { resp.sendError(HttpURLConnection.HTTP_FORBIDDEN, "[InvalidMerchantException]"); return; } } catch (MalformedURLException e) { resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "[MalformedURLException]"); return; } catch (IOException e) { resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "[IOException]"); return; } finally { if (connection != null) { connection.disconnect(); } } if (cookieHeader == null) { resp.sendError(HttpURLConnection.HTTP_FORBIDDEN, "[InvalidMerchantException] Cookie is null."); return; } String destPath = req.getQueryString(); //strip off the merchant_id and merchant_key destPath = destPath.replaceFirst("(&)?merchant_id=" + merchantId, ""); destPath = destPath.replaceFirst("(&)?merchant_key=" + merchantKey, ""); //go ahead and append auth key, just incase it is required... destPath += "&auth=" + authKey; String destUrl = req.getRequestURI() + "?" + destPath; //if ?& replace it with ? destUrl = destUrl.replaceFirst("\\?&", "?"); resp.addHeader("Set-Cookie", cookieHeader); //resp.addHeader("Cookie", cookieHeader); resp.sendRedirect(destUrl); return; } else { // user was authenticated, GOAL COMPLETE! resp.setContentType("text/plain"); resp.getWriter().print(user.getEmail()); } } catch (Exception ex) { resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "[InternalTransactionException]"); } } private String getParameterValueByName(HttpServletRequest req, String name) { try { String ret = null; Map<String, String[]> parameterMap = req.getParameterMap(); if (parameterMap.containsKey(name)) { ret = parameterMap.get(name)[0]; } return ret; } catch (Exception ex) { return null; } } } --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-java@googlegroups.com To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en -~----------~----~----~----~------~----~------~--~---