« OpenID and "High Security" | Main | OpenID IPR: Please Comment! »

March 20, 2007

OpenID for Desktop Clients

The itch I had is that I have a network client that communicates with a server using HTTP as a communication protocol (doesn't have to be HTTP, but its simpler to work with). It could be an IM client on the desktop, for example, that uses HTTP as a communication protocol (or any REST-based interface). They key is that the client and server share some persistent state (like a cookie-based session).

I want to have the user present their OpenID to the desktop client application and have them do normal OpenID authentication (which happens through the browser). Below, I describe what I implemented to make that happen (I implemented this with a simple python command-line desktop client, and a pylons-based openid provider, but the choice of implementation is not important - if you want to see my code, please ask - I haven't tied it up in a pretty bow yet).

The basic idea is to have the desktop client ask the server component to initiate openid through the client and then through a browser living on the user's desktop. That browser session and the client "session" with the application server are associated with a nonce (generated by the application server). From an OpenID perspective, the application server is the RP, and the OP is the same OP you would normally use with the openid. The desktop client is just a proxy for the app living on the desktop that kicks off the normal browser-based authentication session on behalf of application server.

Another way to think of it is that instead of a HTML Form POST initiating the OpenID authentication process, its the desktop application kicking off the authentication process.

Here's a rough description:

  1. Desktop client listens on localhost port 9876 (http) to receive notification that the openid auth session was successful or not. We'll see why later.

    To initiate login, it first does a request to the server component to associate the desktop client's http session to the server component with an openid, and a nonce:

    GET on http://servercomponent.com/client-auth/=gmw

  2. Server component returns:

    302 relocated
    Location: http://servercomponent.com/client-login/<nonce>


    In generating this 302 response, the server associates the nonce with desktop client's HTTP session, and the openid requested by the desktop client.
  3. The desktop client gets the 302 and does NOT follow the redirect itself. Instead, it makes the local web browser (e.g. python's webbrowser.open) go to
    http://servercomponent.com/client-login/<nonce>

    Note: the desktop client and its HTTP session are now associated (by the server component) with the user's web browser session via the nonce.

  4. The server component looks up openid by nonce and does openid discovery, returns a redirect to OP to the browser, with return_to set to:

    http://servercomponent.com/client-complete/<nonce>

  5. OpenID auth happens as normal (user browser goes off to OP to authenticate)
  6. The user browser eventually returns to

    http://servercomponent.com/client-complete/<nonce>

  7. In response to #6 server component returns a http redirect to http://localhost:9876 - this redirect can contain status information which lets the desktop client app know whether there was success or failure. Of course, the server component (on servercomponent.com) knows about the sucess or failure of course since it is a normal RP and has done normal OpenID auth in step 5. The desktop client, in response to this request, can try to close the browser window, or give the user a friendly status message.

The result is that the desktop client has gotten an indication that authentication was successful (though it could discover that from the servercomponent.com if it needed to). The server component knows that the session associated with the nonce is authenticated because that nonce was used to initiate openid on the browser. Thus, the client can be trusted by the server to be associated with the identifier that the client initially requested to be authenticated.

I'm trying to find issues with this approach - please do contact me with issues you do find.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83455eeb869e200d8342fa76d53ef

Listed below are links to weblogs that reference OpenID for Desktop Clients:

Comments

Just understand that your idea still requires that the user *absolutely* trusts the client software with a username and password. Just because the client appears to be opening a regular browser window does not mean that it's not opening a second, hacked installation (modified upon the software client install).

Here are a couple other variations on your theme:

-- Embed a Web browser in the desktop app itself, such as Gecko. That makes the OpenID work happen fully within the application rather than through an external browser. Monitoring browser progress through events might even eliminate the need to do the localhost:9876 socket.

-- When the user launches the "program", the icon or whatever spawns both a Web browser (visible) and your application (not yet visible, but with your localhost:9876 socket). The browser opens onto a traditional OpenID login page, and login proceeds like it would if they were logging into a local site. If you make your OpenID process be specific to your desktop app, the server can just "know" to redir to localhost:9876 upon completion, which triggers popping up the first application window and, perhaps, closing the browser.

Basically, I agree with bmuller that having login split between an app and a browser might be a bit disconcerting for users.

I've been thinking about a simular solution. (As you can see on my blog). I make the client act as a browser, instead of using a browser, but then some really good html form parsing code needs to be written.

But there are a few security implications, also noted in my blog.

BTW, you should check out OAuth since this idea was core to the problem we set out to solve.

http://oauth.net

Yes, OAuth is the answer here now! Everyone should go check out oauth.net for this problem now...

Can you please provide me the code for this?

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Gabe's Stuff

Gabe Wachob's Tumblelog

June 2009

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Google Friend Connect