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

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.

We have published an article on OpenID in this month’s BigAdmin newsletter. The article describes the OpenID deployment we have done here at Sun.

One of the feature we were first to demonstrate with OpenID was to increase the trust a Relying Party can have in the principal’s identity by asserting the fact that this principal is also a Sun employee (in addition to the fact that he owns the OpenID URL). This basically supports the approach of whitelisting “acceptable” OpenID OPs (identity providers) from the standpoint of a Relying Party.

Although its usage is far from satisfying (did you say lack of OpenID Relying Parties?), it has been a great way to leverage  OpenSSO and demonstrate its extension mechanism.

Follow

Get every new post delivered to your Inbox.