Wednesday, July 09, 2008

How to make your OpenID Provider case insensitive

In my last post, I discussed why case sensitive OpenID URLs are so important for security.  But case sensitive OpenID URLs are no fun at all for users.  For instance, most users probably expect they could alternate between logging in as www.myprovider.com/myopenidurl and www.myprovider.com/MYOPENIDURL at an RP and be considered the same person.  But if OpenID URLs must be case sensitive, how can this be accommodated?  Let's investigate.

John Bradley suggested the idea to solve the problem (for me anyway): use redirects.  By observing the exact URL of an incoming discovery from a relying party site at a given OpenID URL, the Provider should redirect the discovery if the requested URL was not in the canonical casing for that identifier.  For instance:

  1. Canonical OpenID: myprovider.org/SomeUser
  2. Incoming discovery request: myprovider.org/someuser
  3. OP redirects RP to: myprovider.org/SomeUser
  4. Incoming discovery request: myprovider.org/SomeUser
  5. OP responds: sends OpenID LINK tags or or XRDS document.

If a request comes in for myprovider.org/someuser but the canonical form of the identifier is myprovider.org/SomeUser, then the server should respond to the request with a redirect to myprovider.org/SomeUser.  That way the RP will know immediately what the correct Claimed Identifier should be, will store it in its canonical cased form, and next time the user logs in, this time with myprovider.org/SOMEUSER, it will again be redirected to myprovider.org/SomeUser and the user will be identified as the same person.  John's a smart guy. :)

When you have a case insensitive web server, it will be an easy thing to do this check and redirect because all casing forms of the request will be responded to with the same processing page, which can check the request URL and redirect if necessary.

If you're using a case sensitive web server, you're going to have to capture every single incoming request and do your own checking to see if the URL needs to be redirected, since /someuser and /SomeUser won't both be sent to the same processing page automatically.  Hopefully your web application platform offers some common point to intercept every incoming request and perform special processing on it.  Beware though that it is not enough to just rewrite the URL to the proper casing and send it on its way up your web application stack.  An actual HTTP 301 Redirect must be sent back to the caller to get the right casing to come back as a new request.  This is the only way to get the RP to notice that the Claimed Identifier changed casing to the canonical form.

Note that using this method, no work has to be done at the RP.  So if you're an RP just study and make sure you're compliant with my last post.  If you're an OP you can implement this post's suggestion and your users logging in to any RP will automatically benefit from the convenience of their case insensitive OpenID URLs.

No comments:

Post a Comment