Thanks to my colleague Hua Cui, our OAuth implementation for OpenSSO is now upgraded to the latest 1.0a revision of the spec. There is no legacy support for (now deprecated) the 1.0 version (the version field hasn’t been changed in OAuth which, to me at least, does suggest deprecation of the previous release).

Since the signature mechanism in itself is not changed, there’s no update necessary to our Jersey OAuth signature library.

Give it a try!

In previous posts, I mentioned we have implemented an OAuth signature library for Jersey (the JAX-RS reference implementation). This signature library sports client and server filters to insulate the application from most of the OAuth signature process (signing on the client side and verifying the signature on the server). Our main goal is to allow Jersey developers to adopt OAuth to secure their messages. Our initial need though, was for our OpenSSO project which now includes an OAuth Token Service.

In doing some testing on the OpenSSO use of OAuth, we noted there’s was a bug in the server verification code of an RSA signature. I’m happy to announce that the fix is in so you can now happily use RSA-SHA1 to secure OAuth messages (in OpenSSO or simply using Jersey). Similarly to HMAC-SHA1, we have created a comprehensive test for the RSA-SHA1, reusing the same test case used here. If you want to use the library, you should take a look at the test source code.

One thing to note is that all signature algorithm implementations (HMAC-SHA1, RSA-SHA1, more could be added.) use the same interface object class OAuthSignature method. The challenge with that is that those algorithm require different types of secrets (as reflected in the OAuth spec). It is especially true for key-based algorithms like RSA-SHA1 where the sign() method requires a different secret (the private key) than the verify() method (called by the server, using the client’s public key).

In our implementation both methods take an OAuthSecrets object in argument. In the case of a public/private key-based algorithm, this object is expected to contain the private key (or public key in the verification case) within the consumerSecret field. This is indicated in the library’s Javadoc.

On the client side, signing (with RSA-SHA1) a message is quite simple. All you need to sign your message is three elements: the request, the OAuth parameters and your public key. The code below shows how you’d do that with Jersey:

        OAuthParameters params = new OAuthParameters().realm(REALM).
         consumerKey(CONSUMER_KEY).
         signatureMethod(RSA_SIGNATURE_METHOD).timestamp(RSA_TIMESTAMP).
         nonce(RSA_NONCE).version(VERSION);

        OAuthSecrets secrets = new OAuthSecrets().consumerSecret(RSA_PRIVKEY);

        OAuthSignature.sign(request, params, secrets);

On the server side, we retrieve the parameters from the request and use the public key (obtained from the client’s X509 certificate). A short example would be:

        params = new OAuthParameters();
        params.readRequest(request);
        secrets = new OAuthSecrets().consumerSecret(RSA_CERTIFICATE);
        assertTrue(OAuthSignature.verify(request, params, secrets));

When it comes to software, I like to try all available features (even the most obscure ones) and sometimes I end up in a situation where my chances of recovery seem pretty slim. I recently managed just that by setting my OpenSSO top realm (/) to inactive
Why would I do such thing I hear you say? Well I was trying to solve some issues related to our OpenID 2.0 extension and was experimenting with various realms, so there you have it…

The result of this great inspiration of mine is that I could not log anymore to the admin console; a tad annoying…
The solution (thanks to Shivaram!) is to edit the LDAP configuration tree and change the value of ou=services,dc=opensso,dc=java,dc=net and set it back to active. That’s it, you’re in!

Now me thinks we should change the console so as to prevent this from being possible…

The great thing about being involved in a community like OpenSSO is that you get to meet people (virtually at least) with all kinds of background and knowledge. In my last blog entry I described the standard way of deploying DSEE on Solaris (using DSCC and Java Web Console). While discussing just that on the OpenSSO IRC channel, nettezzaumana described a DSCC-free process to install DSEE. He’s posted it as a comment to my previous entry, check it out!

As you all know, Directory Services are key to OpenSSO. We support many of them but, beside OpenDS which we use for our embedded configuration store, one of the best LDAP Directory server out there is Sun’s Directory Server Enterprise Edition (DSEE for short). In a typical deployment you will want to store user data on a separate Directory Service.

I always thought that, starting from a freshly installed Solaris 10 box, the deployment of DSEE is everything but smooth. This post lists the initial steps one has to take to perform such deployment and follow the DSEE Administration guide (your sole reference on the matter) . This was also strongly inspired by some excellent posts (listed at the end).

First a few assumptions:

  • Our starting point is a machine that runs  Solaris 10. I used the latest release (Sept. ’09) available here. All updates were applied after the installation.
  • I’ll assume the installation is done as root. This might not be the optimal approach, security-wise, but I’m keeping it simple here.
  • I’m installing DSEE via the JES 5 installer. JES (Java Enterprise System) is our main delivery system for lots of Sun’s software. The neat thing about JES is that it bundles applications together (e.g. Access Manager 7.1 and DSEE). In the present case I only installed DSEE and DSCC, the DS Control Center (a useful interface to administer DSEE deployments).

Now onto the steps:

  1. The first step to be done is to configure DSCC by performing:
    <dsee install dir>/dscc6/bin/dsccsetup initialize
    Doing so results in an error from cacao: Cannot find property: [cacao embedded].
    The problem here is that JES reverted the version of cacao (Solaris’ Common Agent Container (more info here) to a previous one.
  2. We need to reinstall cacao from the Solaris 10 CD. Look for the 2 following packages: SUNWcacaort, SUNWcacaodtrace To install them, change to the packages directory and enter:
    pkgadd -d . SUNWcacaort
    pkgadd -d . SUNWcacaodtrace
  3. Start cacao: /usr/sbin/cacaoadm start
    You can verify it’s running fine with: cacaoadm status
  4. You can now re-attempt to run the initialization (step 1). You should see a message saying that the DSCC Registry has been created successfully.
  5. If you want to make sure cacao starts upon reboot, enter:
    /usr/sbin/cacaoadm enable
  6. The the admin guide says to access DSCC through the Java Web Console in your browser. Well, we need to make sure it is running first:
    /usr/sbin/smcwebserver status

    Most likely it’s not…
  7. Start the Java Web Server with:
    smcwebserver start
    Now you can access it with your browser and … Oops… it only listens on your localhost (127.0.0.1).
    To fix this, use svccfg:
    # /usr/sbin/svccfg
    # svc:> select system/webconsole
    # svc:/system/webconsole> setprop options/tcp_listen=true
    # svc:
    /system/webconsole>quit
    You’ll have to restart the Java Web Console at this point:
    /usr/sbin/smcwebserver restart
  8. The Java Web Console is now accessible on the standard port 6789 (using https) and Voilà, the configuration of DSEE as specified in the Administration guide can now proceed unhindered.

Was this useful? Did you have a different DSEE install experience? If so, please let me know!

Some very useful links I used for this post:

  1. http://oldmangriffous.blogspot.com/2008/10/centralised-authentication-on-solaris_26.html
  2. http://www.tjhsst.edu/admin/livedoc/index.php/Sun_Java_System_Directory_Server

Today we just added support in our OpenID extension (note to myself: this page needs a serious update…) for another OpenID 2.0 feature: realm & RP validation.

As described in the OpenID 2.0 specification, it is important for an IdP (sorry I mean an OP in OpenID parlance) to verify that the Relying Party (RP) return_to URL (that is the endpoint the browser will be redirected to once authentication has happened at the OP) is indeed an OpenID endpoint. The OP should also verify that this return_to URL is within the realm of the RP. This validation is done by having the OP perform a Yadis-based discovery of the RP (see here for more details).

The OpenID4java library, upon which is built our extension, already supports this validation. To leverage this feature in your OpenSSO deployment, you’ll have to do the following (I’m assuming you already have deployed the OpenID extension; if not, see this post):

  1. Create an XRDS document that you’ll host at the RP site.This file describes the RP endpoint and will be retrieved by the OP. At a minimum the file contains one service description with one endpoint (your return_to URL). To folllow up on the deployment I described in previous posts, my XRDS document (I named it yadis.xml) contains the following information:
    <?xml version="1.0" encoding="UTF-8"?>
       <xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)"
                  xmlns:openid="http://openid.net/xmlns/1.0">
       <XRD>
          <Service xlmns="xri://$xrd*($v*2.0)">
            <Type>http://specs.openid.net/auth/2.0/return_to</Type>
            <URI>http://opensso.example.com:49723/consumer-servlet</URI>
          </Service>
       </XRD>
    </xrds:XRDS>
    
  2. In the Provider.properties file (see previous post) add the following property: openid.provider.enforcerpid=true (or false if you don’t want it…)

That’s it; now when your RP makes an authentication request, the OP will validate the RP’s endpoint.

In my previous blog on deploying the OpenID extension with OpenSSO, there is a step (step #3 for OpenSSO) in which you have to add the OpenID attribute you created to OpenSSO’s embedded OpenDS directory.
To be more explicit, a way to achieve this is to connect to you OpenSSO DS store and run the following ldif fragment:

dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( 2.16.840.1.113730.3.1.9990 NAME ‘openid-attributes’ DESC ‘Persisted attributes (OpenID)’ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN ‘
Attributes (OpenID)’ )

add: objectClasses
objectClasses: ( 2.16.840.1.113730.3.2.9999 NAME ‘openiduser’ DESC ‘Class to hold the OpenID related attributes’ SUP top AUXILIARY MAY ( uid $
openid-attributes ) X-ORIGIN ‘OpenID Attributes object class’ )

To connect to the OpenSSO embedded store, I recommend you use a tool (e.g. Apache Directory Studio). Feed it with the relevant information: hostname (i.e. opensso.example.com), port (usually 50389) and possibly your encryption method.

Of course, tune the ldif example above to the same name (here openid-attributes) you used in amUser.xml