Monday, May 12, 2008

OpenID

Some text is excerpted from Official Specification.

[Resources]

Official web site: http://openid.net
Authentication specification: http://openid.net/specs/openid-authentication-2_0.html
Following is a very good and detailed tutorial about how to develop a web site which makes use of OpenID: http://www.plaxo.com/api/openid_recipe.
Libraries written in various languages: http://wiki.openid.net//Libraries.
This web site lists many web sites which support OpenID: http://openiddirectory.com/.

[Introduction]
       Previously, when we visit some web sites and want to leave comments, generally we need to sign up an account at first. This is kind of annoying because we might just surf the web and we might not visit the website again in the future. Applying for a new account is not a big deal.
       By using OpenID, we can be authenticated in a new web site by signing in an OpenID provider (e.g. Blogger, Flickr, Youtube…) with existing account. In other words, we could use the same account to log in to multiple web sites/applications. Generally, most of users have account in prevailing OpenID providers. These providers (e.g. Flickr, Youtube ...) provide their own core compelling services (e.g. video sharing, picture share…) besides OpenID support. Besides, there are some new sites which mainly provide OpenID support (e.g. myopenid.com,).
       An assumption is that OpenID providers are trusted by various OpenID-aware web applications.
       The advantage of OpenID is that:
       Users can use OpenID to log in to multiple web sites which support OpenID without having to apply for an account. As a result, users don’t need to remember large number of usernames and passwords, which improves user experience greatly.

       The mechanisms used to achieve the goal are: redirection and callback.

[Architecture]
image

1) Background
There are two kinds of communication: direct request and indirect request.
Direct request: one party sends request directly to another party to get response. The message must be encoded as a POST body.
Indirect request: one party sends request to another party by redirecting user agent to the destination party with request data (query string or POST body).
There are two mechanisms which can be used to send indirect request: HTTP indirection or form redirection.
HTTP redirec:
       “Data can be transferred by issuing a 302, 303 or 307 HTTP redirect to the end user’s agent. The redirect URL is the URL of the receiver with the OpenID authentication message appended to the query string.”
HTTP Form redirection
       A HTML page which contains an HTML form element can be returned to user. And the form contains a mapping of keys to values. Javascript can be used to automate submission of the form to implement redirection.
More info: http://openid.net/specs/openid-authentication-2_0.html#anchor6

2) Procedure
First, the Relying Party presents the user with a form that has a field for entering User-Supplied Identifier. The form field’s name should be “openid_identifier” so that user agents can detect it automatically and provide some extra functionality.

Steps:

(1)    The user submits the from to Relying Party
After receiving data submitted by user, Relying Party normalizes the input data and then discovers OP endpoint URL based on user-supplied identifier.

(2)    This step is optional. Relying Party can build an association with OP.
An association establishes a shared secret between them which is used to verify subsequent protocol messages and reduce round trips.
More info: http://openid.net/specs/openid-authentication-2_0.html#associations

(3)     Relying Party sends authentication request to user agent.
User agent sends authentication request to OP. Then user is authenticated by the OP.
These two sub steps jointly do this: Relying Party send an authentication request to the OP to obtain an assertion. This is an indirect request. So the request actually is sent by Relying Party to user agent and then redirected to OP.
Generally, OP will display a web page which enable user to accept or deny access request from Relying Party.

(4)    OP sends authentication response to user agent and then user agent sends response to Relying Party.

(5)    After receiving authentication response from OP (indirect communication), Relying Party verifies it and judge whether it is a positive assertion or negative assertion.

More info: http://openid.net/specs/openid-authentication-2_0.html#responding_to_authentication

[More]
       Besides authentication, personal information (e.g. gender, location, age …) can be transferred between Relying Party and OpenID provider as well. Then Relying Party can pre-fill some registration fields so that users don’t need to type the same information many times. Of course, Relying Party needs to convert information from OpenID provider to its own format.

[Delegation]
Delegation is also possible: http://simonwillison.net/2006/Dec/19/openid/. It means users may want to delegate their OpenID to another provider behind-the-scenes. An example from http://www.plaxo.com/api/openid_recipe:
       “If I try to sign up with the OpenID josephsmarr.com, I may have actually delegated that URL to a different OpenID like jsmarr.myopenid.com, and when the provider returns to you to complete authentication, you need to remember that I wanted to sign up as josephsmarr.com and not jsmarr.myopenid.com.”
Key thing is that you add following two lines of HTML code to your delegation HTML page:
      
<link rel="openid.server" href="http://openid.server">
    <link rel="openid.delegate" href="http://delegation.site">
You should replace the value of href attributes accordingly.

This mechanism actually adds an additional layer which separates Relying party and OpenID provider. Relying Party gets OpenID endpoint URL by accessing your delegation HTML page. After getting value of open.server and openid.delegate, Relying Party can sends authentication request to corresponding OpenID provider. You can easily switch your preferred OpenID provider by modifying value of attribute href in link elements.

[Myth]
       OpenID is a mechanism which can authenticate users by delegating it to corresponding OpenID provider. So it is not appropriate to use it directly in a third-party application which sits on top of an existing service and wants to access the backend service on behalf of the user. For example, if a web site makes use of Youtube API to do some cool things, it necessarily needs users’ information to utilize Youtube on behalf of the user. OpenID does not solve this problem.
       But, in my opinion, this can be done by extending OpenID specification. In authentication response, OpenID provide can include an auth token which can be used as a handle by Relying Party to access service provided by the OpenID provider on behalf of the user. In addition, access level (Read, Write, Delete …) must be negotiated as well.
       However, the extension deviates from gist of OpenID because authorization delegation is involved besides authentication.

No comments: