Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using HTTP Basic-Auth with Google App Engine URLFetch service

How can I specify the username and password for making Basic-Auth requests with App Engine's URLFetch service (in Java)?

It seems I can set HTTP headers:

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

What are the appropriate headers for Basic-Auth?

like image 347
Thilo Avatar asked Aug 27 '09 13:08

Thilo


People also ask

Is Basic Auth safe for API?

Basic authentication is simple and convenient, but it is not secure. It should only be used to prevent unintentional access from nonmalicious parties or used in combination with an encryption technology such as SSL.

Is Basic Auth still used?

Microsoft is discontinuing the use of basic authentication in Exchange Online for various applications, including but not limited to: EAS, POP, IMAP, Remote PowerShell, Exchange Web Services (EWS), Offline Address Book (OAB), Outlook for Windows and Mac.

Is Basic Auth clear text?

With Basic Authentication the user credentials are sent as cleartext and because HTTPS is not used, they are vulnerable to packet sniffing.

What is basic auth in API?

With Basic Authentication, you pass your credentials (your Apigee account's email address and password) in each request to the Edge API. Basic Authentication is the least secure of the supported authentication mechanisms. Your credentials are not encrypted or hashed; they are Base64-encoded only.


5 Answers

This is a basic auth header over http:

Authorization: Basic base64 encoded(username:password)

eg:

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

You will need to do this:

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

And to do that you will want to get a base64 codec api, like the Apache Commons Codec

like image 163
Zombies Avatar answered Sep 27 '22 11:09

Zombies


For those interested in doing this in Python (as I was), the code looks like this:

result = urlfetch.fetch("http://www.example.com/comment",
                        headers={"Authorization": 
                                 "Basic %s" % base64.b64encode("username:pass")})
like image 28
Luke Francl Avatar answered Sep 30 '22 11:09

Luke Francl


You set up an Authenticator before you call openConnection() like this,

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

Since there is only one global default authenticator, this doesn't really work well when you have multiple users doing the URLFetch in multiple threads. I would use Apache HttpClient if that's the case.

EDIT: I was wrong. App Engine doesn't allow Authenticator. Even if it's allowed, we would have the multi-thread issue with a global authenticator instance. Even though you can't create threads, your requests may still get served in different threads. So we just add the header manually using this function,

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);
    }
like image 6
ZZ Coder Avatar answered Oct 01 '22 11:10

ZZ Coder


Using HttpURLConnection gave me some problems (for some reason the server I was trying to connect to didn't accept auth credentials), and finally I realized that it's actually much easier to do using GAE's low-level URLFetch API (com.google.appengine.api.urlfetch) like so:

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

This worked.

like image 4
alibloomdido Avatar answered Sep 27 '22 11:09

alibloomdido


There is a wrapper on Apache HttpClient for App Engine

please go through the post http://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

like image 3
Rahul Garg Avatar answered Sep 29 '22 11:09

Rahul Garg