Apache XMLRPC 1.1 authentication patch

When you are using XML RPC, you often want to have some security mechanism that
will protect your system from malicious users.

One mechanism that could be used is basic HTTP authorization. When this approach
is used username and password from the client are sent as a plain text in the
HTTP header of the request. If authorization is valid, server will process the
request or send response with status code 401 which means that client has not
been successfully authorized. You may argue that plain text as a transport is not
secure enough, but you can always use this mechanism with SSL what will give
you more secure system.

We will focus now on the Apache XML RPC library.
You can achieve this basic authorization by using AuthenticatedXmlRpcHandler
interface. All you have to do is to implement handler and write execute method.

    public Object execute(String method, Vector params, String user, String password)
        throws Exception;

This method has to authenticate user according to the username and password
provided, and do the action specified by the method and params. You have very
nice demo in AuthDemo.java file in the library.

All you have to do next is to make client object, send authorization data and
call execute method of the handler. For the demo handler that would be something
like this:

            XmlRpcClient client = new XmlRpcClient(url);
            try
            {
                client.setBasicAuthentication(username, password);
                client.execute("auth.action", params);
            }
            catch(Exception ex)
            {
                System.err.println("Error: " + ex.getMessage());
            }

This code snippet above would result in call like this:
execute(action, params, username, password) of our handler.

The problem with this approach is that we are responsible for determining
what action should be used which could be a big task in a complex handler. Idea
of this patch is to allow you to expose any of your objects as a handler with
basic authorization.

All you have to do is to make your object implement AuthenticatedHandler
interface and write authorize method:

        public boolean authenticate(String username, String password);

Method should do whatever it takes to check if a username and password belongs
to a valid user. It could connect to a relational database, LDAP or any other user
storage and return true if user is permitted for a call or false otherwise.
Client can make a call to any public method in your handler.

            XmlRpcClient client = new XmlRpcClient(url);
            try
            {
                client.setBasicAuthentication(username, password);
                client.execute("authenticated.test", params);
            }
            catch(Exception ex)
            {
                System.err.println("Error: " + ex.getMessage());
            }

The code snippet will call authenticate method of the handler ant then call
test method with a given params.

Installation

First you will need the source of Apache XMLRPC 1.1 library. You can download
this library from the Apache web site.
Then you should download patch from here

Extract library source and copy the patch in the source directory.
Next you should apply the patch with the following line.

        patch -u -p 1 -i xmlrpc-authenticated.patch

You should see something like:

patching file src/java/org/apache/xmlrpc/AuthenticatedDemo.java
patching file src/java/org/apache/xmlrpc/AuthenticatedHandler.java
patching file src/java/org/apache/xmlrpc/WebServer.java
patching file src/java/org/apache/xmlrpc/XmlRpcServer.java

After patching, you should be able to build your new library with Ant

Testing

AuthenticatedDemo.java is provided for testing and demo purposes.
In order to run demo, you should first include library in your class path. Suppose RPC_PATH is
a path to the library. Do the following:

        export CLASSPATH=.:XMLRPC_PATH/bin/xmlrpc-1.1.jar

Now, start XMLRPC server:

        java org.apache.xmlrpc.WebServer 8080

And finally you can make a call to our handler:

        java org.apache.xmlrpc.AuthenticatedDemo http://localhost:8080
        	authenticated.test test test

If everything is OK, you should get a result like

        Testing

Now we can try bad authentication case with a following line

        java org.apache.xmlrpc.AuthenticatedDemo http://localhost:8080
        	authenticated.test testing testing

And we will get

        Error: org.apache.xmlrpc.XmlRpcException: Username or password does not match

Closing word

We managed to expose our objects to the RPC server with basic
authorization feature without disturbing existing library features. This way
library could be used in some cases where complicated handlers are needed and
still one can use standard authenticated handlers where it is appropriate.

Leave a comment

Your email address will not be published. Required fields are marked *