Java 将HTTP基本身份验证与Google应用程序引擎URLFetch服务一起使用

Java 将HTTP基本身份验证与Google应用程序引擎URLFetch服务一起使用,java,google-app-engine,basic-authentication,Java,Google App Engine,Basic Authentication,如何指定使用App Engine的服务(Java)进行基本身份验证请求的用户名和密码 似乎我可以设置HTTP头: URL url = new URL("http://www.example.com/comment"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("X-MyApp-Version", "2.7.3");

如何指定使用App Engine的服务(Java)进行基本身份验证请求的用户名和密码

似乎我可以设置HTTP头:

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

基本身份验证的合适头是什么?

在像这样调用openConnection()之前,您设置了一个验证器

Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password.toCharArray());
    }
});
因为只有一个全局默认身份验证器,所以当多个用户在多个线程中执行URLFetch时,这并不能很好地工作。如果是这样的话,我会使用ApacheHttpClient

编辑:我错了。应用程序引擎不允许验证器。即使允许,全局验证器实例也会出现多线程问题。即使您无法创建线程,您的请求仍可能在不同的线程中得到服务。因此,我们只需使用此函数手动添加标题

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);
    }

ApacheHttpClient上有一个appengine的包装器

请通过邮局


这是http上的基本身份验证标头:

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

例如:

您需要执行以下操作:

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,就像第一个答案上的注释:setRequestProperty应该获得不带冒号的属性名(“Authorization”而不是“Authorization:”)。

对于那些有兴趣在Python中这样做的人(就像我一样),代码如下所示:

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

使用
HttpURLConnection
会给我带来一些问题(出于某种原因,我试图连接的服务器不接受身份验证凭据),最后我意识到使用GAE的低级URLFetch API(
com.google.appengine.API.URLFetch
)实际上要容易得多,比如:


这很有效。

那么,这真的是一个应用程序引擎问题吗?只需查看HTTP RFC,了解如何进行基本身份验证(提示-‘授权’)。我希望App Engine可能有一个类似于Apache HttpClient的方便包装器,这样我就不必手动设置(和base64编码)授权标头。App Engine上只有一个线程。。。(顺便问一下,是否有任何文档可以保证这种情况?)我们对此有一些问题,我认为是线程问题。下周我回到办公室时,我会和实现这个的人核实一下。刚才和那个把我们的应用程序移植到谷歌的人谈过。看我的编辑。这就是我最后做的。由于我将username:password作为属性放在appengine-web.xml中,所以我直接将编码版本放在那里,所以我甚至不需要编解码器。(您可以使用openssl命令行:echo-n“username:password”| openssl enc-base64)+1这也解决了我即将遇到的HTTP身份验证问题。谢谢哦,getBytes()需要另一个)来关闭setRequestProperty。我相信代码应该如下所示:result=urlfetch.fetch(,headers={“Authorization”:“基本%s”%base64.encodestring(“用户名:密码”)[:-1]});更新为使用base64.b64encode。我知道它有效,因为它是我在实际代码中实际使用的。这应该是可以接受的答案,您还可以设置超时:FetchOptions FetchOptions=FetchOptions.Builder.withDeadline(10);HTTPRequest req=new HTTPRequest(fetchurl,HTTPMethod.GET,FetchOptions);
result = urlfetch.fetch("http://www.example.com/comment",
                        headers={"Authorization": 
                                 "Basic %s" % base64.b64encode("username:pass")})
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()));