使用HTTP Basic-Auth和Google App Engine URLFetch服务

如何使用App Engine的URLFetch服务(使用Java)指定用于生成Basic-Auth请求的用户名和密码?

我似乎可以设置HTTP标头:

URL url = new URL("http://www.example.com/comment"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("X-MyApp-Version", "2.7.3"); 

Basic-Auth的适当标题是什么?

这是一个基于http的基本身份validation标头:

授权:基本base64编码(用户名:密码)

例如:

 GET /private/index.html HTTP/1.0 Host: myhost.com Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 

你需要这样做:

 URL url = new URL("http://www.example.com/comment"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Authorization", "Basic "+codec.encodeBase64String(("username:password").getBytes()); 

要做到这一点,你将需要一个base64编解码器API,如Apache Commons Codec

对于那些有兴趣在Python中执行此操作的人(就像我一样),代码如下所示:

 result = urlfetch.fetch("http://www.example.com/comment", headers={"Authorization": "Basic %s" % base64.b64encode("username:pass")}) 

在调用openConnection()之前设置一个Authenticator,

 Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password.toCharArray()); } }); 

由于只有一个全局默认validation器,当多个用户在多个线程中执行URLFetch时,这实际上不能很好地工作。 如果是这样的话,我会使用Apache HttpClient。

编辑:我错了。 App Engine不允许使用Authenticator。 即使允许,我们也会遇到全局身份validation器实例的multithreading问题。 即使您无法创建线程,您的请求仍可能在不同的线程中提供。 所以我们只需使用此函数手动添加标题,

 import com.google.appengine.repackaged.com.google.common.util.Base64; /** * Preemptively set the Authorization header to use Basic Auth. * @param connection The HTTP connection * @param username Username * @param password Password */ public static void setBasicAuth(HttpURLConnection connection, String username, String password) { StringBuilder buf = new StringBuilder(username); buf.append(':'); buf.append(password); byte[] bytes = null; try { bytes = buf.toString().getBytes("ISO-8859-1"); } catch (java.io.UnsupportedEncodingException uee) { assert false; } String header = "Basic " + Base64.encode(bytes); connection.setRequestProperty("Authorization", header); } 

使用HttpURLConnection给了我一些问题(由于某种原因,我尝试连接的服务器不接受身份validation凭据),最后我意识到使用GAE的低级URLFetch API( com.google.appengine.api.urlfetch实际上要容易得多。 com.google.appengine.api.urlfetch )像这样:

 URL fetchurl = new URL(url); String nameAndPassword = credentials.get("name")+":"+credentials.get("password"); String authorizationString = "Basic " + Base64.encode(nameAndPassword.getBytes()); HTTPRequest request = new HTTPRequest(fetchurl); request.addHeader(new HTTPHeader("Authorization", authorizationString)); HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request); System.out.println(new String(response.getContent())); 

这很有效。

Apache HttpClient for App Engine上有一个包装器

请查看posthttp://esxx.blogspot.com/2009/06/using-apaches-httpclient-on-google-app.html

http://peterkenji.blogspot.com/2009/08/using-apache-httpclient-4-with-google.html

注意第一个答案:setRequestProperty应该获取没有冒号的属性名称(“授权”而不是“授权:”)。