Uncategorized


I’m happy to report that we’ve fixed an issue in the percent encoding step of our OAuth signature library for the Jersey framework. The issue reported was caused by the fact that we were using Java’s URLEncoder and URLDecoder classes to compute OAuth’s signature base string. Unfortunately those classes do not perform an RFC3986 compliant encoding which is required in OAuth. The main difference is that a space character will be encoded as a + when we need it to be escaped as a %20 (more info here).

To fix this, we’ve chosen to leverage Jersey’s UriComponent class. There is one notable difference though with how one would encode a URI (see here for a very detailed explanation of URIs): OAuth says that the signature base string is built by concatenating the request method, the request URL and the normalized parameters (with & to separate them) and that those elements must be encoded (prior to concatenation). In effect we are re-encoding elements that are already encoded. As Paul noted, it’s as if we wanted to pass the signature base string in a URI… I remember this possibility was mentioned in conversations about debugging OAuth deployment but that’s the only case I remember for this.

Anyway, to illustrate this, below is the piece of code where the bulk of the action happens:


StringBuffer buf = new StringBuffer(request.getRequestMethod().toUpperCase());
URI uri = constructRequestURL(request);
String tp = uri.getScheme();
buf.append('&').append(UriComponent.encode(tp, UriComponent.Type.SCHEME));
tp = uri.getAuthority();
buf.append("%3A%2F%2F").append(UriComponent.encode(tp, UriComponent.Type.AUTHORITY));
tp = uri.getPath();
buf.append(UriComponent.encode(tp, UriComponent.Type.PATH_SEGMENT));
buf.append('&').append(UriComponent.encode(normalizeParameters(request, params), UriComponent.Type.QUERY_PARAM));

Our testing code now also includes elements with spaces to make sure we got it right (thanks to Michael Werle).

Advertisements

Here we are now. The European commission has officially blessed Oracle’s bid for Sun Microsystems. I do think Oracle is a great opportunity to rebound and move forward even though sadness and regrets are very much present today. Thanks to James Gosling for creating this great picture below (his blog post is here):

Sun RIP (by James Gosling)

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!

Many people reading my previous posts about our OpenID extension for OpenSSO asked me where is the OP (OpenID Provider) code in the OpenSSO repository. The answer is that there’s no code for it (right now) and the reason for this is that we thought deployers would likely develop their own OP with all the appropriate checks in place. But since I do get these requests and to complete the example I described in previous posts, Below is the source code for the simplest (i.e. dumbest) OP one can think of.

To refresh our memories after the holiday break, the role of the OP web application is to hand out the metadata related to the OpenID identifiers of (presumably known) users. That metadata (in the form of an html page with metadata placed in the <head> section) points to the location of the related OpenID server (for both versions 1 & 2).

In the present example, we will simply hand out that information to any appropriately formed URL (see this post). A real OP should probably verify that the OpenID identifier used corresponds to an existing user.

Please note that for the code below I chose to make my life easier and used the Jersey API to quickly create a simple web application. You can of course use servlets instead (or whatever) but REST is so easy with Jersey!

Apologies for the formatting but the string is way too long to fit in any way I tried. The key parts of that string are the two <link rel=…> elements which define the OpenID endpoints. Of course you’ll need to change those to match your deployment.


import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;

/**
* REST Web Service
*
* @author Hubert A. Le Van Gong <hubert.levangong at Sun.COM>
*/

@Path("/{id}")
public class OP {
@Context
private UriInfo context;

String standard_profile = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE html PUBLIC\"-//W3C//DTD XHTML 1.0 Transitional//EN\"
+ \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\" >\n"
+"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
+ " <head>\n"
+" <link rel=\"openid.server\" href=\"http://openid.example.com:49723/openid/service\"/>\n"
+" <link rel=\"openid2.provider\" href=\"http://openid.example.com:49723/openid/service\"/>\n"
+" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n"
+" <title>OpenSSO OpenID provider</title>\n"
+" <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n"
+" </head>\n"
+" <body>\n"
+" <div class=\"body\">\n"
+" <h2>This OpenID provider is based upon OpenID4Java & supports the following protocols</h2>\n"
+" <UL>\n"
+" <li>OpenID Authentication 2.0</li>\n"
+" <li>OpenID Authentication 1.1 (in compatibility mode)</li>\n"
+" <li>OpenID Attribute Exchange 1.0</li>\n"
+" <li>OpenID Simple Registration 1.0 and 1.1, draft 1</li>\n"
+" </UL>\n"
+" </div>\n"
+" <h2> To see the OpenID ID, view the source of this html page (usually achieved by right-clicking on the page)</h2>"
+" <div>\n"
+" </div>\n"
+" </body>\n"
+"</html>\n";

/** Creates a new instance of OP */
public OP() {
}

/**
* Retrieves representation of an instance of OP
* @return an instance of java.lang.String
*/
@GET
@Produces("text/html")
public String gethtml() {
return standard_profile;
}

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

A quick summary of the OAuth support we’ve recently added in a couple of key projects.

If you’re into RESTful web services and OAuth, we have implemented an extension to the Jersey project (the JAX-RS Reference Implementation). This extension allows for the signing and/or the verification of OAuth 1.0 based requests. It is based on a digital signature library accessed by server and client filters. Detailed information can be found here.

For people interested in a more integrated solution, we have also implemented a module for the open source project OpenSSO to supports OAuth as an authentication module. This module handles the Service Provider side, that is: token issuance, token & message verification as well as SSO session handling (to bridge with other protocols). This module is, for now, an extension to OpenSSO. In other words it is not yet part of the core OpenSSO and should be considered as more experimental. Beside the Java doc, a good source of information on this can be found in this article. There’s also Pat’s demo at Community One this year.

If you’re so inclined, give it a try – any feedback is more than welcome!

The more I think and read about the session fixation issue (see the official announcement here and additional info there) that has been discovered in OAuth, the more I’m convinced of the benefits Identity Federation brings to the table.

Think about it, the main issue (beside securing the callback URL which is reasonably easy to achieve) is the fact that the (service) Consumer and the Service Provider can’t currently be sure that the user that has initiated the OAuth flow (and thus has logged in at the Consumer site) is the same user that logs in the Service Provider during the authorization process. If something akin to SAML‘s SSO model were in play (where identities of the principal at the consumer & SP site are federated in a privacy-preserving manner – meaning no correlation issue) then ensuring it is the same user would be a no brainer.

This also can be looked at from the token perspective and what information it conveys. Wouldn’t a SAML assertion be useful here?

Another interesting path would be to use something like Liberty’s Interaction Service to obtain confirmation from the user thus thwarting an attacker to obtain the access token in your name.

Next Page »