Proposal for an XRI (i-name) profile for OpenID
Victor Grey
victor at 2idi.com
Sun Apr 2 18:45:59 UTC 2006
The following is my proposal for an XRI (i-name) profile for OpenID
SSO. It modifies the identity server discovery steps to use XRI
Resolution, and otherwise is the same as the basic OpenID protocol. The
rest of what appears here is my understanding of the OpenID protocol.
Feedback is very welcome, and most especially from anyone who can
verify (or dispute) that my analysis of OpenID is actually correct.
=vg
---------------------------------------
Proposal for an XRI (i-name) profile for the OpenID SSO protocol
Actors:
Principal - the entity being authenticated (or interchangeably, her
user agent).
SP - the service provider that wishes to authenticate the Principal.
IDA - the provider of an authentication service for the Principal.
The OpenID protocol (as I see it) has six distinct phases:
1. Principal presents the SP with an identity signifier.
2. SP uses the presented identity to discover the URL for the IDA.
3. SP acquires a secret key from the IDA (or a local cache).
4. SP redirects the Principal to the IDA with an authentication request.
5. IDA authenticates the Principal and redirects her to the SP with an
authentication assertion.
6. SP verifies the authentication assertion via the secret key.
Step 3 can alternatively be folded into step 6. (OpenID calls this
"dumb mode.")
The only difference between standard OpenID and the XRI profile is in
steps 1 and 2. In standard OpenID the Principle presents a URL as an
identifier, and the IDA URL is obtained by reading information in the
HTTP header that is returned by the identity URL. In the XRI profile,
the Principal presents an XRI (an i-name or an i-number), and the IDA
URL is obtained by means of XRI resolution.
XRI profile in detail:
1. Principal presents the SP with an i-name or i-number
a. Principal enters i-name in a form field and submits, or
b. i-name or i-number is url-encoded into the GET request query
string (e.g. "http://example.com/login.php?iname=%40example%2Ainame")
or
c. SP retrieves a cookie set on a previous authentication by this
Principal, and determines i-name or i-number from it.
2. SP uses XRI Resolution to discover the Principal's authentication
service URL. If more than one authentication service URL is sent in the
resolution response, the first one in priority order (as defined by XRI
Resolution 2.0) should be tried first, and if that fails, the SP MAY
try the others, in order.
Optionally, resolution data may be cached by the SP for a period of
time specified in the resolution response, and the authentication
service URL retrieved from cache if available on subsequent visits by
the Principal.
3. This is the optional "smart mode". We should consider requiring
smart mode for the XRI profile.
a. SP sends a POST request to the IDA, with the following required
value:
openid.mode=associate
and the following optional values:
openid.assoc_type=HMAC-SHA1
## This is the default if not sent, and the only value presently
available.
openid.session_type=DH-SHA1
## If this is not sent, the IDA will respond in cleartext.
## The IDA may respond in cleartext anyway, at which point the SP
has to decide
## whether to accept it. I propose that for the XRI profile, if
the IDA is
## using an https URL, cleartext over SSL be the recommended
method, to save
## the additional overhead of the Diffie-Hellman processing.
## If openid.session_type=DH-SHA1 is specified, then the following
values apply.
openid.dh_modulus
openid.dh_gen
openid.dh_consumer_public
## OpenID provides libraries in several languages to calculate
these values.
b. IDA responds with a plaintext file (UTF-8 encoded, but only ASCII
is used),
that contains key-value pairs in the format "somekey:somevalue\n".
assoc_type:HMAC-SHA1
## the only type available presently
assoc_handle:xxx
## an opaque handle for this association, must be <= 255 chars,
## in ASCII range 33..126 (printable non-whitespace characters)
expires_in:nnn
## the number of seconds from now within which this association may
be used
session_type:DH-SHA1
## if absent, secret is being sent in cleartext.
## If using Diffie-Hellman:
dh_server_public:base64value
enc_mac_key:base64value ## the encrypted shared secret
## OpenID provides libraries in several languages to calculate
these values.
## SP uses DH library to decrypt the shared secret
## If using plaintext:
mac_key:base64(shared secret value for the association keyed to the
assoc_handle)
4. SP redirects the Principal to the IDA with an authentication
request. This is
necessarily a GET request, and includes the following query string
parameters:
openid.mode
## Value can be checkid_setup or checkid_immediate
## "checkid_immediate" assumes that the IDA can authenticate the
Principal
## without interaction. If this is not the case, see how this is
## handled in step 5 below.
openid.identity
## The XRI from step 1
openid.assoc_handle
## From step 3b
openid.return_to
## URL to which the SP wishes the Principal to be returned. IDA
must preserve
## any query string parameters in the return URL. It is suggested
that
## the SP include a self-signed nonce with local timestamp to
resist
## replay attacks.
openid.trust_root
## Optional. The SP URL that the IDA may show to the Principal for
approval.
## The return_to URL must be descendant from the trust root, by a
set
## of rules described in the OpenID docs.
5. IDA authenticates the Principal and redirects her to the SP with an
authentication assertion in the query string. The redirect URL must
have appended to it the following parameters:
openid.mode
## If the request was made with mode "checkid_immediate", but the
IDA requires
## interaction with the Principal, the mode is set to "cancel" and
a
## user_setup_url is returned. In any case, "cancel" indicates an
## authentication failure, and "id_res" indicates success.
openid.user_setup_url
## See above. SP may choose to redirect the Principal to this URL
with
## a "checkid_setup" request if an original checkid_immediate
request failed.
## If authn is successful, the following params are also sent:
openid.identity
## The XRI being authenticated
openid.assoc_handle
## The assoc_handle to be used by the SP to find the HMAC key to
verify the
## signature. If it doesn't match the one sent in step 4, or the
SP didn't
## send one in step 4 (dumb mode), then see step 6.
openid.return_to
## Must match the value transmitted in step 4.
openid.signed
## Comma-separated list of params which the signature covers,
without
## the "openid" prefix, e.g "mode,identity,return_to"
openid.sig
## base64(HMAC(secret + token_contents)), where token_contents is a
string
## in "key:value\n" format, with the keys as in the above
"openid.signed" (in
## that order), and the values from step 4, and the secret is the
one
## keyed by the "assoc_handle".
## The IDA may also send:
openid.invalidate_handle
## If the server didn't accept the assoc_handle provided in step 4,
it sends
## it back as a value to this key, to tell you to stop using it.
You must then
## do the check_authentication in step 6.
6. SP verifies the authentication assertion via the secret key. If you
can verify the openid.sig you are done. Otherwise,
a. the SP sends a POST request to the IDA, with
the following fields:
openid.mode=check_authentication
openid.*
## All the openid.* response params the SP got back from step 5,
with their
## values, exactly as received.
openid.invalidate_handle
## SP can optionally send this to check that the invalidate_handle
command
## actually came from the IDA
b. The IDA returns, in "key:value\n" format:
is_valid
## "true" or "false"
invalidate_handle
## If present, the SP should delete this handle from its cache.
#########################
Error handling:
This section pertains to protocol/run-time errors, not authentication
errors.
If it's a GET request with bad arguments but a valid return_to URL,
redirect with openid.mode=error and openid.error=Error+Text.
If it's a GET request with bad arguments, and no valid return_to,
return a "400 Bad Request" with any content-type and error message you
want.
If it's a GET request with no arguments, show a 200 text/html saying
"This is an OpenID server endpoint. For more information, see
http://openid.net/"
If it's a POST request with bad/no arguments, return a 400 Bad request
with the key-value response format ("key:value\n"), with a single key
"error" with the natural language text.
Limits:
XRI: 255 bytes
IDA URL: 2047 bytes, including the query string
SP return_to URL: 2047 bytes, including the query string
assoc_handle: 255 chars in ASCII range 33..126
More information about the yadis
mailing list