Blog

Ponderings of a kind

This is my own personal blog, each article is an XML document and the code powering it is hand cranked in XQuery and XSLT. It is fairly simple and has evolved only as I have needed additional functionality. I plan to Open Source the code once it is a bit more mature, however if you would like a copy in the meantime drop me a line.

Atom Feed

Authenticating with Redstone XML-RPC Proxy

Basic HTTP Authentication for Redstone XML-RPC Client

Redstone is an excellent and simple XML-RPC library. Recently when trying to create a simple XML-RPC client using Redstone in some example code for a book I am writing, I needed to be able to authenticate with the 3rd-party XML-RPC server.

The server that I was attempting to communicate with (eXist) requires at least HTTP Basic Authentication for operations that require a user to have been granted various permissions. Redstone provides no explicit functionality for authentication or information on how to achieve such things. However as its Open Source, I dug through the code and discovered that it uses a standard java.net.HttpUrlConnection. Whilst it is quite possible to do HTTP Basic Authentication with HttpUrlConnections by setting the correct HTTP Header, I was making use of Redstone's XML-RPC Proxy facility, to help keep my client code simple, which unfortunately does not expose anymore than an instance of the Interface you proxy. Another quick examination of the Redstone code showed that they were using java.lang.reflect.Proxy to create a dynamic proxy of the provided Interface.

We can use Proxy.getInvocationHandler on our XML-RPC proxy to get the Invocation Handler, which happens to be an instance of redstone.xmlrpc.XmlRpcProxy which offers us the method setRequestProperty(name, value). Any request properties set in this way are set as Headers on the Http Request used by the XML-RPC proxy.

Example code for HTTP Basic Authentication with Redstone XML-RPC Proxy Client

//create your XML-RPC Proxy
final MyInterface rpc = (MyInterface)XmlRpcProxy.createProxy(new URL("http://some-server:8080/xmlrpc"), "", new Class[] { MyInterface.class }, true );

final String username = "your-username";
final String password = "your-password";

//concatenate and base64 encode the username and password (suitable for use in HTTP Basic Authentication)
final String auth = javax.xml.bind.DatatypeConverter.printBase64Binary((username + ":" + password).getBytes());

//set the HTTP Header for Basic Authentication
((XmlRpcProxy)Proxy.getInvocationHandler(rpc)).setRequestProperty("Authorization", "Basic " + auth);

//you can now do authenticated XML-RPC calls with the proxy
rpc.yourMethod();

                    

Adam Retter posted on Saturday, 11th May 2013 at 15.49 (GMT+01:00)
Updated: Saturday, 11th 2013 at May 15.49 (GMT+01:00)

tags: RedstoneXML-RPCJavaHTTPAuthentication

0 comments | add comment

LDAP query for Active Directory User's Primary Group

Java LDAP code for Active Directory

When querying AD (Active Directory) with LDAP (Light-weight Directory Access Protocol), it is possible to easily retrieve a lot of attribute information about a user. However, it is not obvious or straight-forward to understand how to find out the Primary Group that a user belongs to. Whilst you can get a list of groups from the 'memberOf' attribute on the 'user' object class, or even find groups by their members through the 'member' attribute of the 'group' object class, these lists do not include information about the User's Primary Group.

The 'user' Class, does provide a 'primaryGroupID' attribute, however the 'group' class does not contain a matching attribute that you can directly search against. However there is a trick! After quite some Googling and pulling information together from various sources, I have managed to achieve this, and to make it easier for everyone else, I am publishing a complete example.

PS. If you need to find a good LDAP querying and browse tool for examining the objects in AD LDAP, then I found Apache Directory Studio to be absolutely fantastic.

Basically, every object class in AD LDAP has an 'objectSID' identifier. This SID (Security Identifier) is a binary identifier provided as a byte array.

The binary expression of a SID has the following format:
byte[0] - Revision Level
byte[1] - count of Sub-Authorities
byte[2-7] - 48 bit Authority (big-endian)
...and then n Sub-Authorities, 32 bits each (little-endian)

e.g. -
[1,5,0,0,0,0,0,5,21,0,0,0,37,-20,73,58,97,-107,0,-80,109,-55,112,10,47,-24,5,0]                
            

The last sub-authority of a SID is known as the RID (Relative Identifier), and it is this RID that differentiates objects from within the same domain. This basically means that by replacing the RID in an SID you can generate the SID for a different object. The 'primaryGroupID' attribute from the 'user' class is a RID. So, we can take the SID of the user, and replace the RID part with the primary group id, we can then lookup the group in LDAP using this SID as the key.

A binary SID can be decoded into a string, which is both easier to understand and can also be used for subsequent queries within AD LDAP. The specifics of the SID string format can be found here.

The string expression of a SID has the following format:
“S-{Revision}-{Authority}-{SubAuthority1}-{SubAuthority2}...-{SubAuthorityN}”

e.g. -
“S-1-5-21-977923109-2952828257-175163757-387119”
            

I based my code for decoding a binary expression of a SID into a string expression on the code found here but I have tried to simplify and improve on the approach.

Java Code for decoding Binary a SID into a String SID:
/**
* The binary data is in the form:
* byte[0] - revision level
* byte[1] - count of sub-authorities
* byte[2-7] - 48 bit authority (big-endian)
* and then count x 32 bit sub authorities (little-endian)
* 
* The String value is: S-Revision-Authority-SubAuthority[n]...
* 
* Based on code from here - http://forums.oracle.com/forums/thread.jspa?threadID=1155740&tstart=0
*/
public static String decodeSID(byte[] sid) {

    final StringBuilder strSid = new StringBuilder("S-");
    
    // get version
    final int revision = sid[0];
    strSid.append(Integer.toString(revision));
    
    //next byte is the count of sub-authorities
    final int countSubAuths = sid[1] & 0xFF;
    
    //get the authority
    long authority = 0;
    //String rid = "";
    for(int i = 2; i <= 7; i++) {
        authority |= ((long)sid[i]) << (8 * (5 - (i - 2)));
    }
    strSid.append("-");
    strSid.append(Long.toHexString(authority));
    
    //iterate all the sub-auths
    int offset = 8;
    int size = 4; //4 bytes for each sub auth
    for(int j = 0; j < countSubAuths; j++) {
        long subAuthority = 0;
        for(int k = 0; k < size; k++) {
            subAuthority |= (long)(sid[offset + k] & 0xFF) << (8 * k);
        }
        
        strSid.append("-");
        strSid.append(subAuthority);
        
        offset += size;
    }
        
    return strSid.toString();    
}

A complete Java example complete with LDAP query code is available here LDAPTest.java.

Adam Retter posted on Friday, 1st July 2011 at 22.57 (GMT+02:00)
Updated: Friday, 1st 2011 at July 22.57 (GMT+02:00)

tags: Active DirectoryLDAPJavaPrimary GroupSID

1 comments | add comment

Tag Cloud