Simple Comments Release Notes: v.960 (3/3)
Simple Comments Release Notes: v.960
In step 6 of the process described on the previous page, I mentioned that the RP must validate the hash signature as provided by the OP; one way to do that is to send the message back to the OP and ask them if it's legitimate. It's also possible that the RP had already--using Diffie-Hellman key exchange techniques--exchanged a secret signature key with this particular OpenID provider at some point in the past; in which case, the RP can simply recalculate the hash themselves using the shared secret (the OP would have used that same shared secret when they generated the hash in the first place) and compare their version to the version provided by the OP. In this way, the RP can eliminate that extra verification communication that would otherwise be necessary with the OP at the tail end of the process.
Such an association (i.e., the exchange of a specific shared secret) between the RP and OP could theoretically have occurred at any time prior to the actual verification of an OpenID login, but in practice usually occurs as a part of the verification process itself. In the description on the previous page, such an association would normally be attempted between steps 2 and 3 for any OP that the RP has not previously been associated with. Various parameters in the OpenID protocol enable the RP to tell the OP which "association" the OP should use to generate the verification signature (and the "association" would then link to the shared secret, which both sides have stored locally), as well as enable the OP to inform the RP that a particular shared secret is no longer valid (perhaps it expired, or has been compromised). In any event, if the RP is unable to establish a shared secret with an OP, it must validate the final signature manually as described above, by sending an extra request back to the OP.
When we discovered the OpenID document on the previous page, we found embedded within it the OP Endpoint URL that we needed to use to verify the supplied OpenID identifier, but it's also possible we might have found a delegated OpenID and provider, instead.
Delegation allows an individual to create their own OpenID resource page (i.e., an HTML page with the appropriate link tags) that will redirect the RP to the OpenID identifier the individual wishes to use. In such a case, the page would include both the OP Endpoint URL that should be used as well as the local OpenID identifier the individual will use to authenticate themselves to that provider. For example, I've set up one of my own delegation pages on my personal site here: biblestuph.com/openid.html, and within that page we find this code:
<html> <head> <title>OpenID Information Page</title> <link rel="openid2.provider openid.server" href="http://www.myopenid.com/server" /> <link rel="openid2.local_id openid.delegate" href="http://Dan.Ragle.myopenid.com" /> </head>
When I enter in my OpenID as
the RP knows it should send me to http://www.myopenid.com/server for
authentication, passing the id http://Dan.Ragle.myopenid.com. Why would I
want to delegate my OpenID? At some point, I might want to change OpenID providers, and
when I do, I would rather not have to change the OpenID that I actually
use to login to my sites. If I have a delegated ID (as above), I can change the
information within my personal HTML page to point to a new provider, and continue to
login to sites using
with a completely different site providing the actual authentication!
Yadis, XRIs, and XRDS
The OpenID discovery process described on the previous page--where the RP simply hits the URL provided by the end user and parses the OP Endpoint URL from it--is the most basic form of OpenID discovery, and is required to be supported by any entity claiming to support OpenID, but there's also an alternate way to provide the OP Endpoint information, and that is via eXtensible Resource DescriptorS, or XRDS.
A full description of XRDS is a bit out of the scope of this article; for detailed information I refer you to this Wikipedia entry. In brief, XRDS is an XML format that allows an individual to define the specific services that should be utilized in conjunction with a particular resource. Yadis, the original discovery protocol that allowed an RP (or any other entity, for that matter), to locate the appropriate XRDS file from a given URL, was officially incorporated into the OpenID specs in OpenID 1.1 (and subsequently wrapped into XRI Resolution 2.0,).
XRDS documents provide a formal and normalized listing of the various services that can be associated with a particular resource; one such service commonly listed there is an individual's OpenID provider. In fact, a single XRDS can actually list multiple potential OpenID providers; leaving the actual choice up to the RP that requested the document. (For example, if you've written an RP that only knows how to validate OpenID 2.0 IDs, you would need to pick an OpenID provider that supported that spec.)
XRDS was created to support XRI resolutions. And what is an XRI? Again, I'm venturing out of the scope of this article in general, but an XRI can loosely be seen as an abstracted representation of a resource. It allows you to provide a single identifier that could--depending on the context it is used in--refer to a particular Web page, a particular service, a specific E-mail address, a specific location, etc. The result of resolving an XRI is an XRDS document, so it's easy to see how such a context can be applied depending on the needs of the entity consuming the XRI. To elaborate, if a person enters an XRI in a form expecting an OpenID, then the RP (application) behind the form will know to look up the XRDS document from the provided XRI, select from within it the provider that supports a flavor of OpenID known to the RP, and proceed with OpenID authentication using the OP Endpoint URL specified for that provider. A form might provide a single box like this:
(That's just a conceptual example; not an actual working form.) When the user enters an XRI in the box, the back-end application could then look up the XRDS, and select from among potentially multiple authentication services (OpenID, SAML, or some community-specific authentication) to communicate with in an attempt to authenticate the individual.
More about XRIs can be found at its OASIS home page: http://www.oasis-open.org/committees/xri/. In fairness, however, I must point out that XRIs have met with some resistance and criticism on the 'Net; perhaps most notably from the W3C TAG (Technical Architecture Group), which as recently as May of this year wrote:
We are not satisfied that XRIs provide functionality not readily available from http: URIs. Accordingly the TAG recommends against taking the XRI specifications forward, or supporting the use of XRIs as identifiers in other specifications.
As is often the case with new technology, time will tell if the XRI spec will be widely accepted (and thus commonly used). Nonetheless, it's already described in the OpenID 2.0 specifications and any would be OpenID implementors would do well to understand the basics of its implementation.
How does all of this relate to OpenID? As alluded to at several points in the above description, XRIs are described as an acceptable form of identifiers in the OpenID 2.0 specifications; i.e., it's possible that your users may attempt to identify themselves using their XRIs, as opposed to their URL identifiers!
OpenID Extensions and Attribute Exchange
Included within the OpenID specifications is the ability to include extensions, or "piggyback" functionalities that can be included on top of the OpenID protocol via parameters and values embedded within the OpenID messages transferred back and forth between RPs and OPs. Perhaps the most notable of these extensions currently available is OpenID Attribute Exchange, or AX.
As its name implies, OpenID Attribute Exchange allows for the exchange of
attributes pertaining to an individual between an OP and an RP. Specifically,
the RP includes parameters requesting particular pieces of information from the
OP while they're authenticating the individual in question; for example, the
OP, if they support AX, will then send the information they are aware of back
to the RP, which could use the information to build their own
user registration data for the user who is logging in. Out of concern for the
individual's privacy, most OPs will first prompt the user for permission to send
such information before offering it to the RP, or at the very least, require
the user to set up their personal information beforehand and specify which
info can and cannot be sent to the RP's that request it. If you don't already know
what your OP does in this regard, it would be wise to find out!
With Attribute Exchange, the amount of information sent between OPs/RPs is limited only by the number of fields the two parties wish to define and recognize. An earlier form of attribute exchange, called OpenID Simple Registration Extension (or SREG) provided for the passing of eight specific, and common fields typically used to register a user on a site. Many providers still support SREG, and in my limited testing I've found that several which support SREG now support AX (specifically, those providers that support OpenID 2.0 tend to support AX, while those that support OpenID 1.1 tend to support SREG, which is expected since AX and the OpenID extension capabilities were defined after OpenID 1.1).
A further capability of Attribute Exchange (not supported by SREG) is the ability to keep specific pieces of information synchronized between the OP and RP; i.e., whenever you change a particular attribute (your nickname, for example), the OP will send an update of that field to all RPs that have requested to receive it. In this way, an individual could theoretically maintain a single profile on the Web and automatically update each site that they log into with changes to that profile whenever they happen!
The information I've provided so far should give you a good general knowledge of OpenID; though it's still far from exhaustive. I've not mentioned, for example, the OpenID Provider Authentication Policy Extension (or PAPE), which allows an RP to specify to the OP those types of authentications they will honor (as well as allows the OP to inform the RP which authentication methods were actually used), nor have I discussed RP discovery (a process that the OP utilizes in an attempt to verify the authenticity of a specific RP). Nonetheless, the above descriptions should provide you with a strong launching pad for your own OpenID-related projects or discussions.
I've also not said a word about how Simple Comments implements OpenID; I'll take care of that glaring ommission in a followup article which I hope to have posted within the next couple of weeks. For now, I wanted to make the new code available and provide the general OpenID background for those that wanted to pursue it. OpenID is different, and I suspect it won't be everyone's cup of tea. Be sure to give it a fair and thorough reading before coming to your own conclusions.
For now, I will mention that Simple Comments as released today supports associations (for those sites with the right Perl modules installed), XRIs, XRDS discovery (Yadis), and Attribute Exchange; as well as adds the ability of administrators to define their own OP blacklists/whitelists, should they choose to do so. In Part II of this article, I'll return to Simple Comments and discuss some implementation (and especially Perl)-specific considerations that came to light as a result of the Simple Comments OpenID deployment. Stay tuned!
[Editor's note: The followup article referred to in this article is now available at http://www.webreference.com/programming/perl/comments/openid.]
Created: July 8, 2008
Revised: August 1, 2008