我正在尝试使用Java / Groovy客户端访问Google App Engine上受OAuth保护的资源。但是,身份验证无效,我的GET请求只是将Google帐户登录页面HTML恢复。
我使用HTTPBuilder / signpost和google-oauth-java-client获得相同的结果。
这就是我所做的:
http://<my-app>.appspot.com/rest/hello
的“hello world”servlet(实际上是一个Gaelyk groovlet)为我的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帐户登录,登录后我可以访问该servlet。
如下所示在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帐户登录页面。
我已经多次完成上述过程,检查令牌中的复制/粘贴错误,并确保我没有让令牌混淆。
这是使用Groovy 1.8.2,OSX Java 1.6.0_29,HTTPBuilder 0.5.1,gaelyk 1.1。
有什么想法吗?感谢。
答案 0 :(得分:2)
好的,没有回应,所以这就是我如何解决它。
我放弃了使用oauth ...谷歌只为此声称'实验'状态,所以也许它从根本上不起作用。
但是,我使用测试客户端的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");
}
}