Since last week, I have officially become a Neustar employee (I had been consulting for a while). I really owe this opportunity to none other than =PeterD (Peter you really need to update your blog!).
Although I’m primarily involved in spec writing for the UltraViolet project (bringing some additional perspective from the federated identity angle), I also expect to have a cross-organization role in providing support for questions that pertain to identity management, web security or RESTful architecture.
Lots of work (strike that: tons of work!) and lots of smart people in the company (we hire!)
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();
tp = uri.getAuthority();
tp = uri.getPath();
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).
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):
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.
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.
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:
A little tip: deploying a war file on different containers / application servers can lead to different results. Although their scope widely differs, Sun has 2 offerings when it comes to deploying a war file: Sun Java System Web Server (SJWS) and Glassfish.
Well, it turns out that Glassfish replaces the entire content of the directory where the application is deployed while Sun JSWS will simply overwrite the existing files, thus leaving all other files in place. In a recent case, I had copied some properties file in that directory (after a first deployment) and was surprised to find them there after a re-deploy.
Now, I know that I’m not really supposed to mess around with files of a deployed war but I find it to be a good reminder of the sometimes not so subtle differences between containers.
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:
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.
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
Start cacao: /usr/sbin/cacaoadm start
You can verify it’s running fine with: cacaoadm status
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.
If you want to make sure cacao starts upon reboot, enter: /usr/sbin/cacaoadm enable
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:
Most likely it’s not…
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
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!
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):
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:
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:
attributeTypes: ( 2.16.840.1.1137126.96.36.19990 NAME ‘openid-attributes’ DESC ‘Persisted attributes (OpenID)’ SYNTAX 188.8.131.52.4.1.14184.108.40.206.15 SINGLE-VALUE X-ORIGIN ‘
Attributes (OpenID)’ )
objectClasses: ( 2.16.840.1.1137220.127.116.1199 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
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!
OpenSSO acts as an authentication hub and as such supports many different modules. We recently upgraded one of them, OpenID, from OpenID 1.0 to OpenID 2.0. This module was written using both OpenSSO’s client library and OpenID4Java library.
This blog post describes the steps necessary to deploy the OpenID 2.0 extension module for OpenSSO. Once deployed, this module will add both OpenID 1.0 and 2.0 support for your IdP. In OpenID parlance, your OpenSSO deployment can act as an OP (OpenID Provider) and thus authenticate users for OpenID client applications.
In the example below, I will be using 2 different hostnames for clarity purposes: openid.example.com to run the OpenID module and opensso.example.com to run OpenSSO and the OP. Remember to, at a minimum, use 2 separate instances of your application server (I use & recommend Glassfish-v2.1): one for OpenID and the other for OpenSSO.
For the OpenID module
Deploy the openid war file.
Update 3 properties file with values taken from the opensso deployment. Those files are: AMConfig.properties, Provider.properties and ldap.properties (if the OP will be persisting user’s OpenID attributes). Sample configuration files are described at the end of this document.
Add properties files to the Classes directory (e.g. /Applications/NetBeans/glassfish-v2.1/domains/domain2/applications/j2ee-modules/openid/WEB-INF/classes/ on my Mac). Note that the domain MUST be restarted once those files have been added. Also at the moment, these files will have to be copied each time the openid war file is (re)deployed.
Add openid.example.com in the list of realm aliases
(Access Control tab → top realm → General tab)
Add an OpenID attribute to OpenSSO’s user schema. To do so, insert the following attribute in the <user> section of amUser.xml: <AttributeSchema name=”ldap.people.return.attribute” type=”single” syntax=”string”
This file should be located in your opensso deployment directory under …/config/xml/ (or WEB-INF/classes/).
Enable self update of OpenID attribute in the ldap directory: to do so you have 2 choices (thanks to Rajeev for this tip):
If you have a LDAP editor:
connect to embedded config store directory (default : localhost:50389)
login as user cn=Directory Manager )
navigate to dn: ou=SelfWriteAttributes,ou=Policies,ou=default
Edit the sunKeyValue attribute to add the openID attribute declared in OpenSSO’s schema: <Value>openid-attibutes</Value> or
Using the addwriteperm.ldif (see content of this file at the end of this document):
Edit the file addwriteperm.ldif and insert the OpenID attribute (openid-attibutes).
Execute the shell command: $DS/ldapmodify -h localhost -p 50389 -a -f ~/bin/addwriteperm.ldif
-D “cn=Directory manager” -w password
You need to add LDAP attributes to the users data store. Log in OpenSSO as admin, browse to the Data Store tab, select the appropriate store (or the users) and add openiduser to the LDAP User Object list and openid-attributes to the LDAP User Attributes list.
Restart your app server.
Below are sample configuration files (only key configuration values are being shown).
To test your OpenID deployment you will need to have a web application that hands out OpenID identifiers as well as an OpenID client application (this is in addition to the OpenID extension and the OpenSSO instance described above). We also assume you have some users registered in the OpenSSO instance.
We’ve created a very simple application (OP.war) that will serve OpenID identifiers of the form: http://your_hostname/OP/resources/user_name. Note that in its current form the identifier will point to an OP deployed at the following URL: http://openid.example.com:49723/openid/service If your deployment URL differs, you’ll have to edit the (only) java file and change that link (in 2 places) before re-compiling the war file. In our example, we’ll deploy the OP in the same domain than the OpenSSO instance, at the URI (http://opensso.example.com:8080/OP/).
A way to verify the OP is to visit a URI of the form http://opensso.example.com:8080/OP/resources/username where username can be anything. You should see some text explaining what the OP is based on but more importantly you can right-click on the page to take a look at the html source of the page. Note the OpenID metadata present in the HTML <head> section of the page.
OpenID4Java (the library that was used to create the OpenID extension) offers a nice little OpenID client application (Consumer-servlet) that lets you test both OpenID 1.0 and OpenID 2.0 (with persistance of attributes).
In our example, we’ll deploy the OpenID client application in the same domain than the OpenID extension, at the URI: (http://openid.example.com:49723/consumer-servlet/).
2 scenarios can be tested:
OpenID 2.0 Authentication
This scenario demonstrates OpenID-based delegated authentication with an OpenSSO IdP.
Visit the OpenID Service Provider (aka. Relying Party)
You’re redirected to OpenSSO login page. Log in with the credentials of a known user. Note that the user must correspond to the provided OpenID identifier. That mapping is determined by the pattern declared in the Provider.properties file (with the openid.provider.identity_pattern property).
The next page is the OpenID verification (or consent) page.
Click on trust.
You’re now logged in the blog site.
OpenID 2.0 Authentication with Simple Registration Exchange
In addition to delegated authentication, this demonstrates the provisioning of attributes to the Relying Party.
Before starting, close all browser windows (or clean cookies) to make sure you don’t have a live session at the IdP.
Select (or de-select) the attributes that will be provided at the same time authentication takes place (make sure to leave at least one selected).
You’re now redirected to OpenSSO for authentication. Enter the credentials of the corresponding user.
In addition to the same consent page, notice the attributes that were requested. Fill up those information. You can chose to have those attributes remembered, in which case they will be persisted in the ldap directory.
Click on trust.
You’re now back at the Relying Party site on a page that shows the query string and the attributes requested.
As mentioned before, during this last JavaOne, my colleague Pat Patterson has been showing a demo that leverages JavaFX and our OpenSSO’s OAuth module (preview for now). Daniel Raskin (our OpenSSO marketing guru at Sun) and him have created a video about the demo here. Check it out, it’s informative and very funny.