Some people need to use a username and password to access resources (such as images) using HTTP URLs. This page describes how to set up HTTP Basic Authentication so FOP can access password-protected resources. The first method described here is very simple but may have issues when you are in a J2EE environment. The second method doesn't have this issue.

The Authenticator

You can register a small helper class derived from java.net.Authenticator with the JavaVM. It acts as an agent when an URL is accessed that needs a username and a password. Take the source code below and adjust it to your needs:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class MyAuthenticator extends Authenticator {

    /**
     * @see java.net.Authenticator#getPasswordAuthentication()
     */
    protected PasswordAuthentication getPasswordAuthentication() {
        System.out.println("Host: " + this.getRequestingHost());
        System.out.println("Port: " + this.getRequestingPort());
        System.out.println("Protocol: " + this.getRequestingProtocol());
        System.out.println("Scheme: " + this.getRequestingScheme());
        System.out.println("Prompt: " + this.getRequestingPrompt());

        return new PasswordAuthentication("myusername", "mypassword".toCharArray());
    }

    public static final void install() {
        Authenticator.setDefault(new MyAuthenticator());
    }
    
}

To make it active, just call the static install() method somewhere in the initialization code of your application, web application or whatever.

MyAuthenticator.install();

How it works

When FOP encounters a fo:external-graphic with a "src" property that points to a password-protected image, it simply builds a java.net.URL instance and tries to open a stream (openStream()) to download the image. The java.net.URL subsystem receives a request from the web server to enter the username and password which it forwards to the Authenticator object. Since you set the default Authenticator by calling install() as seen above the get!PasswordAuthentication() method gets called. Your MyAuthenticator classreturns the right username and password, and the HTTP request can be completed.

Subclassing FOURIResolver

A recent change in FOP Trunk allows you to subclass FOURIResolver and handle HTTP authentication on a case-by-case basis.

URIResolver myResolver = new FOURIResolver() {
    protected void updateURLConnection(URLConnection connection, String href) {
        String effURL = connection.getURL().toExternalForm();
        if (effURL.startsWith("http://myspecialhost/") {
            applyHttpBasicAuthentication(connection, "myusername", "mypassword");
        }
    }
};
userAgent.setURIResolver(myResolver);

You can easily inspect the URI (href parameter) or the URL itself (connection.getURL()) if you want to supply a different password (or none) depending on the resources to be accessed.

Links

HowTo/BasicHttpAuthentication (last edited 2009-09-20 23:52:38 by localhost)