2012-01-31 3 views
1

Java/Groovy 클라이언트를 사용하여 Google App Engine에서 OAuth로 보호 된 리소스에 액세스하려고합니다. 그러나 인증이 작동하지 않고 GET 요청이 Google 계정 로그인 페이지 HTML을 다시 가져 오는 중입니다.Google App Engine에서 oauth 보호 된 리소스에 액세스

HTTPBuilder/signpost와 google-oauth-java-client를 사용하면 동일한 결과가 나타납니다. 여기

내가 무슨 짓을했는지의 : 배포 된 http://<my-app>.appspot.com/rest/hello
  • 에 매핑 된 '안녕하세요'서블릿 (실제로는 Gaelyk은의 groovlet)를 만든 http://ikaisays.com/2011/05/26/setting-up-an-oauth-provider-on-google-app-engine/
  • 에 설명 된대로

    • 는 OAuth를 제공 설정 서블릿을 gae에 보내고 브라우저를 통해 확인할 수 있음을 확인했습니다.
    • 내 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> 
      
    • 은 브라우저 GET는 Google 계정 로그인이 필요한 것을 확인하고는 로그인 후 나는 서블릿에 액세스 할 수 있습니다.

    • 액세스 및 클라이언트 비밀 토큰을 얻기 위해 3-legged OAuth가 http://groovy.codehaus.org/modules/http-builder/doc/auth.html에 설명 된대로 춤 췄습니까?
    • (위의 링크에서 다음 지침)

      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 계정 로그인 페이지이기 때문에 어설 션이 실패 다음과 같이 위해 RESTClient에서 토큰을 사용합니다.

    • google-oauth-java-client를 사용할 때도 동일한 문제가 발생합니다.

    위의 과정을 여러 번 거쳤으며 토큰의 복사/붙여 넣기 오류를 확인하고 토큰이 섞이지 않도록했습니다.

    이것은 Groovy 1.8.2, OSX Java 1.6.0_29, HTTPBuilder 0.5.1, gaelyk 1.1입니다.

    아이디어가 있으십니까? 감사.

  • 답변

    2

    좋아요, 이에 대한 응답이 없으므로 여기에 제가 어떻게 작동했는지 나와 있습니다.

    나는 oauth ... google을 사용하는 것을 포기했으나 어쨌든이 실험용 상태는 '실험적'이라고 주장하기 때문에 근본적으로 아직 작동하지 않습니다.

    그러나 나는 매우 유용한 기사 http://www.geekyblogger.com/2011/05/using-clientlogin-to-do-authentication.html에 기반 (구글의 Gmail에 액세스 할 때 당신이 할 것과 같은 계정에 수동으로 로그인을하고 상당) 내 테스트 클라이언트에서 ClientLogin에 프로토콜을 사용하여 좋은 결과

    를 얻을. 다음과 같은 몇 가지 방법으로 코드를 확장해야했습니다.

    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");   
        }   
    
    }   
    
    관련 문제