Доступ к защищенному oauth-ресурсу в Google App Engine - PullRequest
1 голос
/ 31 января 2012

Я пытаюсь получить доступ к OAuth-защищенному ресурсу в Google App Engine с помощью клиента Java / Groovy.Однако проверка подлинности не работает, и мои запросы GET просто возвращают HTML-страницу входа в учетную запись Google.

Я получаю те же результаты с HTTPBuilder / signpost и с google-oauth-java-client.

Вот что я сделал:

  • Установите провайдера OAuth, как описано в http://ikaisays.com/2011/05/26/setting-up-an-oauth-provider-on-google-app-engine/
  • Создан сервлет 'hello world' (на самом деле это Groovlet Gaelyk), сопоставленный сhttp://<my-app>.appspot.com/rest/hello
  • Развернул сервлет в 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 и что после входа я могу получить доступ к сервлету.

  • Танец 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.

  • Я получаю то же поведение при использовании google-oauth-java-client.

Я уже несколько раз проходил этот процесс,проверка на наличие ошибок копирования / вставки в токенах и обеспечение того, чтобы я не перепутал токены.

Это с Groovy 1.8.2, OSX Java 1.6.0_29, HTTPBuilder 0.5.1, gaelyk 1.1.

Есть идеи?Спасибо.

1 Ответ

2 голосов
/ 23 февраля 2012

ОК, нет ответа на этот вопрос, вот как я это обошел.

Я отказался от использования oauth ... Google в любом случае претендует только на "экспериментальный" статус, так что, возможно, он пока что принципиально не работает.

Однако я получаю хорошие результаты, используя протокол ClientLogin от моего тестового клиента (эквивалентно ручному входу в учетные записи Google, как тот, который вы делаете при доступе к gmail)

Я основал это на чрезвычайно полезной статье http://www.geekyblogger.com/2011/05/using-clientlogin-to-do-authentication.html. Мне пришлось расширить ее несколькими способами, код ниже:

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("myemail@gmail.com", 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");        
    }        

}        
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...