August 2009


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

  1. Deploy the openid war file.

  2. 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.

  1. 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.

For OpenSSO

  1. Add openid.example.com in the list of realm aliases
    (Access Control tab → top realm → General tab)

  2. 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”
    any=”display” i18nKey=”openid-attributes”></AttributeSchema>

    This file should be located in your opensso deployment directory under …/config/xml/ (or WEB-INF/classes/).

  3. Add this OpenID attribute to OpenSSO’s embedded ldap directory (I use Apache Directory Studio)

  4. Enable self update of OpenID attribute in the ldap directory: to do so you have 2 choices (thanks to Rajeev for this tip):

    1. If you have a LDAP editor:

      1. connect to embedded config store directory (default : localhost:50389)

      2. login as user cn=Directory Manager )

      3. navigate to dn: ou=SelfWriteAttributes,ou=Policies,ou=default
        ,ou=OrganizationConfig,ou=1.0,ou=iPlanetAMPolicyService,
        ou=services,o=sunamhiddenrealmdelegationservicepermissions,
        ou=services,dc=opensso,dc=java,dc=net

      4. Edit the sunKeyValue attribute to add the openID attribute declared in OpenSSO’s schema:
        <Value>openid-attibutes</Value> or

    2. Using the addwriteperm.ldif (see content of this file at the end of this document):

      1. Edit the file addwriteperm.ldif and insert the OpenID attribute (openid-attibutes).

      2. Execute the shell command:
        $DS/ldapmodify -h localhost -p 50389 -a -f ~/bin/addwriteperm.ldif
        -D “cn=Directory manager” -w password

  5. 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.

  6. Restart your app server.

Configuration Files

Below are sample configuration files (only key configuration values are being shown).

AMConfig.properties

Provider.properties

ldap.properties

  • ldap.host=opensso.example.com
  • ldap.port=50389
  • ldap.bind.dn=cn=Directory Manager
  • ldap.bind.pwd=adminadmin
  • ldap.people.base=dc=opensso,dc=java,dc=net
  • ldap.people.return.attribute=openid-attributes
  • ldap.people.attribute.nodes=firstname,lastname,fullname,nickname,email,
    gender,dob,postcode,country,
    language,timezone
  • ldap.people.search.attribute=uid

addwriteperm.ldif

  • dn:
    ou=SelfWriteAttributes,ou=Policies,ou=default,ou=OrganizationConfig,ou=1.0,
    ou=iPlanetAMPolicyService,ou=services,o=sunamhiddenrealmdelegationservicepermissions,
    ou=services,dc=opensso,dc=java,dc=net
    changetype: modify
    replace: sunKeyValue
    sunKeyValue: xmlpolicy=<?xml version=”1.0″ encoding=”UTF-8″?><Policy name=”SelfWriteAttributes” referralPolicy=”false” active=”true” ><Rule name=”user-read-rule”> <ServiceName name=”sunAMDelegationService” /> <ResourceName name=”sms://*dc=opensso,dc=java,dc=net/sunIdentityRepositoryService/1.0/application/*” /> <AttributeValuePair> <Attribute name=”MODIFY” /> <Value>allow</Value> </AttributeValuePair> </Rule> <Subjects name=”Subjects” description=””> <Subject name=”delegation-subject” type=”AuthenticatedUsers” includeType=”inclusive”> </Subject> </Subjects> <Conditions name=”AttrCondition” description=””> <Condition name=”condition” type=”UserSelfCheckCondition”> <AttributeValuePair><Attribute name=”attributes”/><Value>sunIdentityServerDeviceStatus</Value><Value>telephonenumber</Value><Value>userpassword</Value><Value>givenname</Value><Value>mail</Value><Value>sn</Value><Value>cn</Value><Value>iplanet-am-user-password-reset-options</Value><Value>postaladdress</Value><Value>sunIdentityServerDeviceKeyValue</Value><Value>preferredlocale</Value><Value>description</Value><Value>iplanet-am-user-password-reset-question-answer</Value><Value>openid-attributes</Value> </AttributeValuePair> </Condition> </Conditions> </Policy>


Testing your deployment

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.

  1. Visit the OpenID Service Provider (aka. Relying Party)
    http://openid.example.com:49723/consumer-servlet/
  2. In the (Sample 1) OpenID Username, enter the OpenID identifier:
    http://opensso.example.com:8080/OP/resources/username

    and click on Login
  3. 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).
  4. The next page is the OpenID verification (or consent) page.
    Click on trust.
  5. 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.

  1. Before starting, close all browser windows (or clean cookies) to make sure you don’t have a live session at the IdP.
  2. Browse to the Relying Party at to the following URL:
    http://opensso.example.com:49723/consumer-servlet/
  3. In the Sample 2 box, enter the same OpenID identifier as above (username being anything you want):http://opensso.example.com:8080/OP/resources/username
  4. 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).
  5. You’re now redirected to OpenSSO for authentication. Enter the credentials of the corresponding user.
  6. 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.
  7. You’re now back at the Relying Party site on a page that shows the query string and the attributes requested.