<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
        {mso-style-priority:99;
        mso-style-link:"Balloon Text Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:8.0pt;
        font-family:"Tahoma","sans-serif";}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.BalloonTextChar
        {mso-style-name:"Balloon Text Char";
        mso-style-priority:99;
        mso-style-link:"Balloon Text";
        font-family:"Tahoma","sans-serif";}
.MsoChpDefault
        {mso-style-type:export-only;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal>I am not sure if this belongs in the spec list, but I’ll
give it a try.<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>I would like to suggest adding some text to section 11.1 (or
anywhere else that’s appropriate) that will provide guidelines for using
OpenID in a scenario where the OpenID RP is not the site the user is actually
using. The OpenID specification is written with some bias towards
implementation in a website environment which is the most common use. My aim is
to use OpenID as the authentication method for establishing API sessions. I am
building a web service where the client (any user of the API) requests to
create a session token which can then be used to bypass authentication for a
certain period of time (nothing new here).<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>The API with HTTP Basic auth it looks something like:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><a href="https://api.example.com/session/open.xml">https://api.example.com/session/open.xml</a>
- with the plaintext username and password in the HTTP header, returns an XML
reply with a session token<o:p></o:p></p>
<p class=MsoNormal><a
href="http://api.example.com/session/close.xml?session-id=unqiue_token">http://api.example.com/session/close.xml?session-id=unqiue_token</a><o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>Each user will have a local username and password. I was
trying to avoid it at first but with the current state of OpenID, it might
cause problems as some OP are unreliable and users can end up locked out if
their only access is with the one OpenID they setup their access with. The plan
is to provide an OP for local users (so that any local user is also an OpenID),
and to also allow users to associate any other OpenID with their account. Once
a user adds another OpenID to their account, they can use that to create a
session via:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><a
href="http://api.example.com/session/openid/initiate.xml?openid=some_id&return-url=client_side_capture&realm=optional_client_realm&is-immediate=true">http://api.example.com/session/openid/initiate.xml?openid=some_id&return-url=client_side_capture&realm=optional_client_realm&is-immediate=true</a><o:p></o:p></p>
<p class=MsoNormal><a
href="http://api.example.com/session/openid/validate.xml?response-url=op_endpoint_redirection_url">http://api.example.com/session/openid/validate.xml?response-url=op_endpoint_redirection_url</a><o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>For example, a USER logs into a WEBSITE which is built on
top of a web SERVICE. The SERVICE requires OpenID authentication (the SERVICE
is the RP). The USER login request is sent via AJAX to the SERVICE with a
return_to URL able to capture the OP reply and send it back to the SERVICE. The
SERVICE reply to the AJAX code with the checkid_immediate URL. The AJAX code
calls the checkid_immediate given and captures the redirection reply. The AJAX
code calls a second SERVICE API call providing the OP reply to the checkid_immediate
request. The SERVICE validates the reply and answers with a SERVICE session.
The AJAX code the stores the session id in a cookie and uses it for other API
calls.<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>The same logic can be used with checkid_setup and a server
side API call. The USER is redirected by the AJAX script to the checkid_setup
URL received from the initiate API call. The user signs-in and is redirected
back to the WEBSITE client_side_capture page with the OpenID query parameters.
The WEBSITE server page client_side_capture receives the request, calls the
SERVICE validate API, and redirects the USER back to the WEBSITE with the
session cookie.<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>This voids the first step in section 11.1 since the RP
receives the OP reply via an API call that is not the same as the return-to
URL. In order to keep the transaction secure, I have added another signature to
the return_to parameter. This way when the WEBSITE returns the OP reply to the
API validate call, the SERVICE can make sure that the original return_to was
created by it, and not by the WEBSITE. The normal openid.sig signature will
make sure the OP reply is valid for the entire input. This is the an example
API call and reply:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>API call:<o:p></o:p></p>
<p class=MsoNormal><a
href="http://api.example.com/session/openid/initiate.xml?openid=eran.pip.verisignlabs.com&return-url=http://www.example.com/capture">http://api.example.com/session/openid/initiate.xml?openid=eran.pip.verisignlabs.com&return-url=http://www.example.com/capture</a><o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>API reply:<o:p></o:p></p>
<p class=MsoNormal><a
href="http://pip.verisignlabs.com/server?openid.ns=http%3A%2F%2Fopenid.net%2Fsignon%2F1.1&openid.mode=checkid_setup&openid.identity=http%3A%2F%2Feran.pip.verisignlabs.com%2F&openid.return_to=http%3A%2F%2Fwww.example.com%2Fcapture%3Fnouncer.nonce%3D2301694855%26nouncer.sig%3DFFcpLk7S09X60WJSgIEBSWFk2vU%3D&openid.trust_root=http%3A%2F%2Fwww.example.com%2Fcapture">http://pip.verisignlabs.com/server?openid.ns=http%3A%2F%2Fopenid.net%2Fsignon%2F1.1&openid.mode=checkid_setup&openid.identity=http%3A%2F%2Feran.pip.verisignlabs.com%2F&openid.return_to=http%3A%2F%2Fwww.example.com%2Fcapture%3Fnouncer.nonce%3D2301694855%26nouncer.sig%3DFFcpLk7S09X60WJSgIEBSWFk2vU%3D&openid.trust_root=http%3A%2F%2Fwww.example.com%2Fcapture</a>
<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>Given the increasing focus on web services, it will be very
helpful to include some guidelines in the specification as to how to implement
something like the above protocol and how to ensure it is done in a secure
manner (I will gladly contribute the text). Any thought are greatly
appreciated, as well as letting me know this might not be the right place for
such a discussion…<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>Thanks,<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>Eran Hammer-Lahav (=eran)<o:p></o:p></p>
<p class=MsoNormal>Hueniverse, LLC<o:p></o:p></p>
<p class=MsoNormal><a href="http://hueniverse.com">http://hueniverse.com</a><o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
</div>
</body>
</html>