2012-01-31 94 views
1

我試圖使用Java/Groovy客戶端訪問Google App Engine上的受OAuth保護的資源。但是,身份驗證不起作用,我的GET請求只是將Google帳戶登錄頁面HTML帶回。訪問Google App Engine上的受oauth保護的資源

我使用HTTPBuilder/signpost和google-oauth-java-client獲得相同的結果。

這裏是我做了什麼:

  • 設立一個OAuth提供者在http://ikaisays.com/2011/05/26/setting-up-an-oauth-provider-on-google-app-engine/
  • 創建映射了一個 '世界你好' 的servlet(實際上是Gaelyk的Groovlet)描述http://<my-app>.appspot.com/rest/hello
  • 部署的servlet to gae並確認我可以通過瀏覽器進行GET。
  • 爲我的web.xml添加了安全性約束並重新部署。

    <security-constraint> 
         <web-resource-collection> 
          <web-resource-name>Rest</web-resource-name> 
          <url-pattern>/rest/*</url-pattern> 
         </web-resource-collection> 
         <auth-constraint> 
          <role-name>*</role-name> 
         </auth-constraint> 
    </security-constraint> 
    
  • 證實,一個瀏覽器中得到需要一個谷歌帳戶登錄和登錄後,我可以訪問servlet。

  • 做了三足式OAuth舞蹈作爲http://groovy.codehaus.org/modules/http-builder/doc/auth.html描述來獲得訪問和客戶端祕密憑證。
  • 使用令牌的RESTClient實現如下(在上面的鏈接下面的說明)

    def client = new RESTClient('http://<my-app>.appspot.com') 
    def consumerKey = <my consumer key> 
    def consumerSecret = <my consumer secret> 
    def accessToken = <my access token> 
    def secretToken = <my secret token> 
    client.auth.oauth consumerKey, consumerSecret, accessToken, secretToken 
    def resp = client.get(path:'/rest/hello') 
    assert resp.data == 'Hello world' 
    
  • 因爲響應是谷歌帳戶登錄頁面斷言失敗。

  • 當使用google-oauth-java-client時,我得到相同的行爲。

我已經完成了上述幾個過程,檢查標記中的複製/粘貼錯誤,並確保我沒有混入令牌。

這與Groovy 1.8.2,OSX Java 1.6.0_29,HTTPBuilder 0.5.1,gaelyk 1.1。

任何想法?謝謝。所以這裏

回答

2

OK,沒有這方面的反應就是我的工作圍繞它。

我放棄了使用OAuth ... Google只要求「實驗性」的地位這個反正所以也許它根本還沒有工作。

但是我得到使用的ClientLogin協議從我的測試客戶端,我根據這個就非常有用的文章http://www.geekyblogger.com/2011/05/using-clientlogin-to-do-authentication.html了良好的效果(等同於做一個手動登錄到谷歌帳戶就像使用Gmail時,你做的一個)

。我不得不在幾個方面擴展,代碼如下:

import java.io.File;   
import java.io.InputStream;   
import java.io.LineNumberReader;   
import java.io.StringReader;   
import java.nio.charset.Charset;   

import org.apache.commons.io.IOUtils;   
import org.apache.http.Header;   
import org.apache.http.HttpResponse;   
import org.apache.http.client.HttpClient;   
import org.apache.http.client.methods.HttpGet;   
import org.apache.http.client.methods.HttpPost;   
import org.apache.http.entity.mime.MultipartEntity;   
import org.apache.http.entity.mime.content.StringBody;   
import org.apache.http.impl.client.DefaultHttpClient;   

import com.google.appengine.repackaged.com.google.common.io.Files;   
import com.google.cloud.sql.jdbc.internal.Charsets;   

public class Login {   

    public static void main(String[] args) throws Exception {   
     // This file contains my   
     // google password. Note that this has to be an app-specific   
     // password if you use 2-step verification   
     File passFile = new File("/Users/me/pass.txt");   
     String pass = Files.toString(passFile, Charsets.UTF_8);   
     String authCookie = loginToGoogle("[email protected]", pass,   
       "http://myapp.appspot.com");   
     DefaultHttpClient client = new DefaultHttpClient();   
     // A te   
     HttpGet get = new HttpGet("http://myapp.appspot.com/rest/blah");   
     get.setHeader("Cookie", authCookie);   
     HttpResponse response = client.execute(get);   
     response.getEntity().writeTo(System.out);   
    }   

    public static String loginToGoogle(String userid, String password,   
      String appUrl) throws Exception {   
     HttpClient client = new DefaultHttpClient();   
     HttpPost post = new HttpPost(  
       "https://www.google.com/accounts/ClientLogin");   

     MultipartEntity reqEntity = new MultipartEntity();   
     reqEntity.addPart("accountType", new StringBody("HOSTED_OR_GOOGLE",   
       "text/plain", Charset.forName("UTF-8")));   
     reqEntity.addPart("Email", new StringBody(userid));   
     reqEntity.addPart("Passwd", new StringBody(password));   
     reqEntity.addPart("service", new StringBody("ah"));   
     reqEntity.addPart("source", new StringBody(  
       "YourCompany-YourApp-YourVersion"));   
     post.setEntity(reqEntity);   
     HttpResponse response = client.execute(post);   
     if (response.getStatusLine().getStatusCode() == 200) {   
      InputStream input = response.getEntity().getContent();   
      String result = IOUtils.toString(input);   
      String authToken = getAuthToken(result);   
      post = new HttpPost(appUrl + "/_ah/login?auth=" + authToken);   
      response = client.execute(post);   
      Header[] cookies = response.getHeaders("SET-COOKIE");   
      for (Header cookie : cookies) {   
       if (cookie.getValue().startsWith("ACSID=")) {   
        return cookie.getValue();   
       }   
      }   
      throw new Exception("ACSID cookie cannot be found");   
     } else   
      throw new Exception("Error obtaining ACSID");   
    }   

    private static String getAuthToken(String responseText) throws Exception {   
     LineNumberReader reader = new LineNumberReader(new StringReader(  
       responseText));   
     String line = reader.readLine();   
     while (line != null) {   
      line = line.trim();   
      if (line.startsWith("Auth=")) {   
       return line.substring(5);   
      }   
      line = reader.readLine();   
     }   
     throw new Exception("Could not find Auth token");   
    }   

}   
相關問題