OpenID

From WhyNotWiki
Jump to: navigation, search

OpenID  edit   (Category  edit)


Contents

What is it? Why should I care?

http://nonsmokingarea.com/blog/2007/01/04/openid-distributed-authentication-services/. Retrieved on 2007-05-11 11:18.

OpenID is a vendor-independent approach on bringing the infamous concept of single sign-on to the web. In a nutshell, OpenID allows users to use a single, URI-based token to access numerous OpenID-enabled websites.

Error on call to Template:cite web: Parameter url must be specified. Retrieved on 2007-05-11 11:18.

OpenID is an open, decentralized, free framework for user-centric digital identity. OpenID starts with the concept that anyone can identify themselves on the Internet the same way websites do—with a URI [...].


How to use it

http://openid.net/get/

http://www.intertwingly.net/blog/2007/01/03/OpenID-for-non-SuperUsers. Retrieved on 2007-05-11 11:18.

... Given such an identity, copy the following into the head section of your weblog, adjusting the two URIs as appropriate:

<link rel="openid.server" href="http://www.myopenid.com/server" />
<link rel="openid.delegate" href="http://samruby.myopenid.com/" />

That’s pretty much it. What this says is that the web page in question is owned by the owner of http://samruby.myopenid.com/ and furthermore http://www.myopenid.com/server may be used to verify ownership of http://samruby.myopenid.com/.

By claiming your blog or homepage in this fashion, you can then use your URI (i.e., the URI of your blog or homepage) as your identity. Having this level of indirection is a good thing. If you ever become dissatisfied with your identity provider for whatever reason, you can easily and transparently switch providers.

...

This next step is entirely unnecessary, but I suspect that it will be popular with many of the readers of this blog. Letting someone else host your identity is actually good from a security perspective, after all, any fool can vouch for themselves (and below, I’ll show you how), but having somebody else vouch for you is often better, if for no other reason, it gives the person who is checking up on you a place to report spammers.

...

There is also control issues. After all, what good is a decentralized identity system where your only real choice is to delegate to a centralized server that you don’t control?

...

So far, you have been able to host your own identity, but let’s face it, the URIs are a bit crufty, eh?. This shouldn’t matter much to anyone, but cleaning this up a bit will provide a bit of future proofing should you ever want to use a different implementation to host your own identity.

...


Troubleshooting: "kvToSeq warning: Line 2 does not contain a colon" error

At first, when I had this in my yadis.xrdf:

    <Service priority="1">
      <Type>http://openid.net/signon/1.0</Type>
      <URI>http://TylerRick.com/id</URI>
      <openid:Delegate>http://TylerRick.com/id</openid:Delegate>
    </Service>

, it was giving me this error:

Checking http://tylerrick.com/...
Fetching http://tylerrick.com/
Yadis links found at http://tylerrick.com/id/other/yadis.xrdf. Your server is at http://TylerRick.com/id and it knows you as "http://TylerRick.com/id".
Attempting to associate with the server.
kvToSeq warning: Line 2 does not contain a colon: '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n<html>\n<head>\n<title>phpMyID</title>\n<link rel="openid.server" href="http://tylerrick.com/id/" />\n<link rel="openid.delegate" href="http://TylerRick.com/id/" />\n\n<meta name="charset" content="iso-8859-1" />\n<meta name="robots" content="noindex,nofollow" />\n</head>\n<body>\n<p>This is an OpenID server endpoint. For more information, see http://openid.net/<br/>Server: <b>http://TylerRick.com/id/</b><br/>Realm: <b>OpenID</b><br/><a href="http://TylerRick.com/id/?openid.mode=login">Login</a> | <a href="http://TylerRick.com/id/?openid.mode=test">Test</a></p>\n</body>\n</html>\n'
...

The solution was to add a trailing / to my URI:

    <Service priority="1">
      <Type>http://openid.net/signon/1.0</Type>
      <URI>http://TylerRick.com/id/</URI>
      <openid:Delegate>http://TylerRick.com/id/</openid:Delegate>
    </Service>

It must have encountered a redirect from http://TylerRick.com/id to http://TylerRick.com/id/ and not known how to handle it?? I still don't really understand why one worked and the other didn't.

Troubleshooting: "Falling back to plain text association session from DH-SHA1" warning

I was getting the line:

Falling back to plain text association session from DH-SHA1

when I tried to verify my OpenID. Full output:

Checking http://id.tylerrick.com/...
Fetching http://id.tylerrick.com/
OpenID links found at http://id.tylerrick.com/. Your server is at http://id.tylerrick.com/ and it knows you as "http://id.tylerRick.com/".
Attempting to associate with the server.
Falling back to plain text association session from DH-SHA1
Server contacted successfully.
Try logging in.

http://id.tylerrick.com/?openid.mode=test

bcmath  warn - not loaded
gmp     pass - n/a
logfile warn - log is not writable
session pass
secret  pass
expire  pass
base64  pass
hmac    pass
bigmath fail - big math functions are not available.
sha1_20 pass
x_or    pass

Apparently I need one of bcmath, gmp, or bigmath available in order for it to "work".

Following the instructions at http://wiki.dreamhost.com/Installing_PHP5, I recompiled PHP5 with --enable-bcmath.

bcmath  pass
gmp     pass - n/a
logfile warn - log is not writable
session pass
secret  pass
expire  pass
base64  pass
hmac    pass
bmpowmod-1      pass
long    pass
bmpowmod-2      pass
bin     pass
sha1_20 pass
x_or    pass

Now -- although it takes a couple seconds longer to load -- I no longer get that warning, and it looks like it is able to communicate with its super-encrypted niceness intact:

Checking http://tylerrick.com/...
Fetching http://tylerrick.com/
Yadis links found at http://id.tylerrick.com/yadis.xrdf. Your server is at http://id.tylerRick.com/ and it knows you as "http://id.tylerRick.com/".
Attempting to associate with the server.
Server contacted successfully.
Try logging in.

Yadis for OpenID provider discovery

http://yadis.org/wiki/Main_Page

Yadis is cool. Use it. Love it.

How to get it so I can use http://tylerrick.com/ as my OpenID URI rather than http://id.tylerrick.com/ using Yadis

Attempt 1: RewriteRule ^$ http://id.tylerrick.com/yadis.xrdf

Using the technique recommended by Sam Ruby, I set up an .htaccess for http://tylerrick.com like so:

RewriteCond %{HTTP_ACCEPT} application/xrds\+xml
RewriteCond %{HTTP_ACCEPT} !application/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)
RewriteCond %{REQUEST_URI} !id
RewriteRule ^$ http://id.tylerrick.com/yadis.xrdf [R,L]

What does that 2nd regular expression condition mean? It is basically saying that it must not match application/xrds\+xml;q=0(\.0{1,3})? (the \s* bits in there simply allow white space between the important parts). In other words (as I understand it), if the user agent has application/xrds+xml listed in their HTTP_ACCEPT request-header as a non-preferred type (q<0.1 -- so q=0, q=0.0, etc.), then we don't match for this rewrite rule.

Here are some tests I ran to convince myself of that:


> php -a
Interactive mode enabled

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml'); ?>
0

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'application/xrds+xml'); ?>
0

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'application/xrds+xml;q=0.1'); ?>
0

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'application/xrds+xml;q=0.0,'); ?>
1

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'application/xrds+xml;q=0.00'); ?>
1

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'application/xrds+xml;q=0.000'); ?>
1

<?php echo preg_match('/application\/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)/', 'application/xrds+xml;q=0'); ?>
1
 

Now when I check it out at http://www.openidenabled.com/resources/openid-test/checkup/start?openid_url=http%3A%2F%2Ftylerrick.com%2F, it says this:

Fetching http://tylerrick.com/
Yadis links found at http://id.tylerrick.com/yadis.xrdf. Your server is at http://id.tylerrick.com/ and it knows you as "http://id.tylerrick.com/".

When I checked my log file, it said that openidenabled.com had used this for an Accept header when it requested http://id.tylerrick.com/yadis.xrdf:

Accept: text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml

How did I get it to log this? I set up Apache to run .xrdf files through PHP and then added some PHP to the top of http://tylerrick.com/, http://id.tylerrick.com/, and http://id.tylerrick.com/yadis.xrdf to log headers:

<?php
$file = fopen('headers_log', 'a');
fwrite($file, "\n");
fwrite($file, $_SERVER['REMOTE_ADDR'] . "\n");
fwrite($file, $_SERVER['SCRIPT_URI'] . "\n");
fwrite($file, 'Accept: ' . $_SERVER['HTTP_ACCEPT'] . "\n");
fclose($file);
?>

When I clicked "Try logging in", it directed my browser to my OpenID server where I logged in and then it went back to the next page said this:

I found OpenID links at http://id.tylerrick.com/yadis.xrdf. My attempt to contact the server at http://id.tylerrick.com/ succeeded. You have successfully signed in with this OpenID. Pass. http://id.tylerrick.com/yadis.xrdf is a working OpenID.

Notice how it said http://id.tylerrick.com/yadis.xrdf is a working OpenID, not http://tylerrick.com/ is a working OpenID

I was also able to test the behavior that my .htaccess file creating by doing this on my command line:

> wget --header='Accept: application/xrds+xml' http://tylerrick.com/ -O-

or

> curl --header 'Accept: application/xrds+xml' http://tylerrick.com/
> curl --header 'Accept: application/xrds+xml' http://tylerrick.com/ --dump-header t >/dev/null 2>&1; cat t; rm t
HTTP/1.1 302 Found
Date: Fri, 28 Mar 2008 02:49:46 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
Location: http://id.tylerrick.com/yadis.xrdf
Vary: Accept-Encoding
Content-Length: 222
Content-Type: text/html; charset=iso-8859-1

I had a similar experience when I tried to set up Basecamp to associate with my OpenID at http://tylerrick.com/. It did so successfully, but then it changed my OpenID to http://id.tylerrick.com/yadis.xrdf!

This is what my log file showed:

72.3.156.114
http://id.tylerrick.com/yadis.xrdf
Accept: application/xrds+xml

24.9.128.209 (my browser)
http://id.tylerrick.com/
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

This is not acceptable. I want http://tylerrick.com/ to be recognized as my OpenID URI, not http://id.tylerrick.com/yadis.xrdf! I thought yadis.xrdf was only used to discover/negotiate the actual OpenID to use -- not to itself be the OpenID URI!

I think what was happening was that the OpenID consumers were requesting http://tylerrick.com/, but then, since they matched the RewriteCond %{HTTP_ACCEPT} application/xrds\+xml condition, they were receiving a 302 response from my server telling them to go to the requested document's "new home" at http://id.tylerrick.com/yadis.xrdf, an instruction they were simply dutifully following. Still, a 302 is only a "temporary" move; I thought agents were supposed to continue to use the old location. "A 302 redirect is used when the resource in question exists under a different URL temporarily, but you want people to continue to use the original URL with which the request was made." [1]

So I don't know why the 302 confuses it, but it's looking like that whole redirecting user agents to http://id.tylerrick.com/yadis.xrdf if they accept application/xrds+xml idea is not a good one!

Here is a thread about whether the page referred to by a 302 (temporary) redirect should be treated as temporary by the relying party or not: http://openid.net/pipermail/general/2007-January/000946.html

The issue is that when somebody requests http://intertwingly.net/blog/ and specifies an Accept: application/xrds+xml header on the request, I do a temporary 302 redirect to http://intertwingly.net/public/yadis.xrdf The question is: when the identity validation is done, what should the RP view as my identity? The original URI (.../blog/) or the "temporary" one (.../yadis.xrdf)? LiveJournal (http://www.livejournal.com/openid/) choses the former. JanRain (http://www.openidenabled.com/resources/openid-test/checkup) choses the latter. IMO, independent of whether or not I should be doing the redirect, the spec should be clear and one or both of these implementations should be changed to conform. My two cents is that the answer should depend on whether it was a permanent redirect (301) or a temporary redirect (302) which was employed. However, if consensus forms on this mailing list, I'll update my tutorial accordingly.

Workaround: transparent, internal redirect in Apache

A workaround would be to do an transparent, internal redirect in Apache that doesn't involve sending any type of redirect code (301, 302, etc.) to the user agent: http://www.intertwingly.net/blog/2007/01/03/OpenID-for-non-SuperUsers. Retrieved on 2007-05-11 11:18.

I did an external, temporary redirect as I wanted to see this activity in my Apache Logs. The current status is that some servers will treat this as a permanent redirect, and use my XRD file as my identity (something that works just fine). Those that care about such things can drop the [R] and replace the URI with either a relative or absolute file path and neither the Identity Provider nor your Apache logs will ever see the redirect happened.

While that would work fine if your target URI (the yadis.xrdf) were on the same domain/subdomain as the requested URI, it doesn't work in my case, because it (http://id.tylerrick.com/yadis.xrdf) is on a different subdomain than the requested page (http://tylerrick.com/).

Tests:


You can see that it works in this case:

RewriteRule ^$ /test.html [L]
HTTP/1.1 200 OK
...

But as soon as you put an http:// in the target of the RewriteRule, it forces an HTTP redirect (302 by default):

RewriteRule ^$ http://openid.tylerrick.com/yadis.xrdf [L]
> curl --header 'Accept: application/xrds+xml' http://tylerrick.com/ --dump-header t >/dev/null 2>&1; cat t; rm t
HTTP/1.1 302 Found
Location: http://openid.tylerrick.com/yadis.xrdf
 


Attempt 2: X-XRDS-Location: http://id.tylerrick.com/yadis.xrdf

So I removed the RewriteRule ^$ http://id.tylerrick.com/yadis.xrdf [R,L] stuff from http://tylerrick.com/.htaccess and added this in its place:

<IfModule mod_headers.c>
<Files *.html>
    Header always set X-XRDS-Location http://id.tylerrick.com/yadis.xrdf
</Files>
</IfModule>

Now when I go to http://www.openidenabled.com/resources/openid-test/checkup/start?openid_url=http%3A%2F%2Ftylerrick.com%2F, I get this:

Fetching http://tylerrick.com/
Yadis links found at http://tylerrick.com/. Your server is at http://id.tylerrick.com/ and it knows you as "http://id.tylerrick.com/". Attempting to associate with the server.

Notice that it says "Yadis links found at http://tylerrick.com/" whereas before it said "Yadis links found at http://id.tylerrick.com/yadis.xrdf" -- this is an improvement!

When I clicked "Try logging in", it came back to the page and said this:

I found OpenID links at http://tylerrick.com/. My attempt to contact the server at http://id.tylerrick.com/ succeeded. You have successfully signed in with this OpenID. Pass. http://tylerrick.com/ is a working OpenID.

(Whereas before it said "http://id.tylerrick.com/yadis.xrdf is a working OpenID".)

When I tried to get Basecamp to associate with my OpenID at http://tylerrick.com/ now, it does so successfully and leaves my OpenID as http://tylerrick.com/! Success!!

This is what my log tells me now:

72.3.156.114
http://tylerrick.com/
Accept: application/xrds+xml

72.3.156.114
http://id.tylerrick.com/yadis.xrdf
Accept: */*

24.9.128.209 (my browser)
http://id.tylerrick.com/
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

The important difference is that first request to http://tylerrick.com/. This didn't show up in my log before, because before it was redirecting to http://id.tylerrick.com/yadis.xrdf rather than serving http://tylerrick.com/ (so the PHP script at http://tylerrick.com/index.html wasn't being run before). Now, however, it does serve up http://tylerrick.com/ -- with a 200 OK code -- and that makes all the difference, apparently!

A test with curl confirms this:

> curl --header 'Accept: application/xrds+xml' http://tylerrick.com/ --dump-header t >/dev/null 2>&1; cat t; rm t
HTTP/1.1 200 OK
Date: Fri, 28 Mar 2008 03:26:40 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-Powered-By: PHP/5.2.3
X-XRDS-Location: http://id.tylerrick.com/yadis.xrdf
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html

Caveat for PHP users (at least for me anyway): Can't use mod_headers and php-cgi

I found that as long as I have my files being handled by the PHP CGI script, I am unable to add/modify headers using mod_headers.

I had this line in my .htaccess:

IfModule mod_headers.c>
<Files *.html>
    Header always set X-XRDS-Location http://id.tylerrick.com/yadis.xrdf
</Files>
</IfModule>

AddHandler php5-cgi .html .htm

And this is what my test returned:

> curl --header 'Accept: application/xrds+xml' http://tylerrick.com/test.html --dump-header t 2>/dev/null; cat t; rm t
Hello
HTTP/1.1 200 OK
Date: Fri, 28 Mar 2008 04:24:27 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-Powered-By: PHP/5.2.3
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html

It's totally ignoring my Header always set X-XRDS-Location

But if I remove the AddHandler php5-cgi .html .htm, it immediately starts to work:

> curl --header 'Accept: application/xrds+xml' http://tylerrick.com/test.html --dump-header t 2>/dev/null; cat t; rm t
<?php
        echo "Hello\n";
?>
HTTP/1.1 200 OK
Date: Fri, 28 Mar 2008 04:21:12 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-XRDS-Location: http://id.tylerrick.com/yadis.xrdf
Last-Modified: Fri, 28 Mar 2008 04:16:56 GMT
ETag: "28bab37-1a-9294be00"
Accept-Ranges: bytes
Content-Length: 26
Vary: Accept-Encoding
Content-Type: text/html

What gives? Is it just Dreamhost or is there some good technical reason why it's not working? More importantly, how do I get it to work?

I searched Google for like an hour with terms like apache mod_headers php but couldn't find anything helpful.

Can I have my identity/delegate URI be different from my server URL?

I want to have this:

    <Service priority="1">
      <Type>http://openid.net/signon/1.0</Type>
      <URI>http://id.tylerrick.com/</URI>
      <openid:Delegate>http://tylerrick.com/</openid:Delegate>
    </Service>

The association step passes:

Fetching http://tylerrick.com/
Yadis links found at http://tylerrick.com/. Your server is at http://id.tylerrick.com/.
Attempting to associate with the server.

But when I try to log in, phpMyId redirects me to http://tylerrick.com/?openid.mode=authorize, which doesn't work. it never sends me back to www.openidenabled.com.

The author of phpMyID responds to someone else who tried to do the same thing for his identity and had the same problem: https://www.siege.org/forum/viewtopic.php?pid=1489 (I've changed the URLs in his example to be my URLs (http://shenme.de/blog/ => http://tylerrick.com/, http://shenme.de/openid/index.php => http://id.tylerrick.com/) to make it fit better in this article):

I wonder if it is possible to have an identity url different from phpMyId Url? For example, I have a website http://tylerrick.com/ and phpMyId lives at http://id.tylerrick.com/. I want to be use http://tylerrick.com/ as myOpenId. The first thing to do, according to the standard, would be to make openid.delegate reference tylerrick.com, but that would be different from openid.server (which is id.tylerrick.com/), something that phpMyId prohibits. I also tried to change idp_url to "tylerrick.com/" with browser redirecting to tylerrick.com/ every time I try to authenticate using this URL.

Actually, what you're trying to do is very common. I think you're just confusing the meanings of "openid.server" and "openid.delegate". phpMyID was intended to operate on the principle of using the two in conjunction. "openid.server" is the URL that will be used by a client site (the site you're trying to log in to) as the place to try and log in. "openid.delegate" tells the client site to use this value, rather than the URL you passed it, to log in to the server as. For phpMyID, you (usually) want them both to have the same value, and both be equivalent to the "Server" string that phpMyID shows on its own default page. Here's how the login process works: 1) You go to a client site and give your URL (http://tylerrick.com/) as an OpenID login. 2) That site (the "client") fetches the URL you just gave it and looks for the "openid.xxx" headers. 3) The client site then opens a connection to the "openid.server" and says that "openid.delegate" is trying to log in. If you don't specify the "openid.delegate" it says that the original URL you gave it is trying to log in. This technique allows you to set up your "login URL" (http://tylerrick.com/) as a proxy to your "identity URL" (http://id.tylerrick.com/). Since phpMyID (by design) only works for one URL at a time, unless you explicitly set the identity URL that you want it to work for, it'll fail unless you either delegate authentication to it, or use the "identity URL" as the "login URL" directly. So... long story short... what you want to put in the <head> section of your blog index page is this: Code:

<link rel="openid.server" href="http://id.tylerrick.com/" />
<link rel="openid.delegate" href="http://id.tylerrick.com/" />

If you strictly follow the instructions in the README file, it should lead you to this setup.

There's probably a way to hack it so it works the way I/we want it to, but it's robably best to just leave it with the delegate pointing to http://id.tylerrick.com/. I'm still able to use http://tylerrick.com/ as my OpenID, which is what I want, so I'm happy.

Caveat: Exact spelling of your OpenID URI is important

When I tried changing the case of my OpenID URI in my yadis.xrdf file (to make it prettier), like so:

    <Service priority="1">
      <Type>http://openid.net/signon/1.0</Type>
      <URI>http://id.tylerRick.com/</URI>
      <openid:Delegate>http://id.tylerRick.com/</openid:Delegate>
    </Service>

and then tried logging in using any OpenID consumer (I tried 2 of them), it fails.

Actually, this might be specific to phpMyID, because this is what I see in the phpMyID log file:

Invalid identity: http://id.tylerRick.com/

IdP URL: http://id.tylerrick.com/

Since they don't match exactly, phpMyID must decide it's invalid and return a failure to the consumer.

Similarly when I try simply removing the trailing /:

Invalid identity: http://id.tylerrick.com

IdP URL: http://id.tylerrick.com/

I don't know if this behavior exists in all OpenID provider implementations or not, but the safest bet (which I would recommend) is to simply be consistent with your OpenID URI: always spell it with the same case and with a trailing space (if there is no file name).

Sites that are using it

http://openid.net/where/

You can use your OpenID on any one of a growing number of sites (nearly ten-thousand) which support OpenID. If one of your favorite sites doesn’t support OpenID yet, ask them when they will!

http://www.37signals.com/openid/

http://simile.mit.edu/mediawiki/index.php?title=Special:Userlogin

...


About / How it works

http://openid.net/ :

OpenID starts with the concept that anyone can identify themselves on the Internet the same way websites do—with a URI (also called a URL or web address).
The first piece of the OpenID framework is authentication -- how you prove ownership of a URI. Today, websites require usernames and passwords to login, which means that many people use the same password everywhere. With OpenID Authentication (see specs), your username is your URI, and your password (or other credentials) stays safely stored on your OpenID Provider (which you can run yourself, or use a third-party identity provider).
To log in to an OpenID-enabled website (even one you've never been to before), just type your OpenID URI. The website will then redirect you to your OpenID Provider to log in using whatever credentials it requires. Once authenticated, your OpenID provider will send you back to the website with the necessary credentials to log you in. By using Strong Authentication where needed, the OpenID Framework can be used for all types of transactions.

http://openid.net/specs/openid-authentication-1_1.html :

OpenID Authenticaion provides a way to prove that an End User owns an Identity URL. It does this without passing around their password, email address, or anything they don't want it to. OpenID is completely decentralized meaning that anyone can choose to be a Consumer or Identity Provider without having to register or be approved by any central authority. End User's can pick which Identity Provider they wish to use and preserve their Identity as they move between Providers. While nothing in the protocol requires JavaScript or modern browsers, the authentication scheme plays nicely with "AJAX"-style setups, so an End User can prove their Identity to a Consumer without having to leave the page they are on. The OpenID Authentication specification does not provide any mechanism to exchange profile information, though Consumers of an Identity can learn more about an End User from any public, semantically interesting documents linked thereunder (FOAF, RSS, Atom, vCARD, etc.). Extensions are being built on top of the foundation created by OpenID Authentication to provide mechanisms to exchange profile information.


How?

3.1. Transforming a HTML Document Into an Identifier
In order for a Consumer to know the Identity Provider authoritative for an Identifier, the End User must add markup to the HEAD section of the HTML document located at their URL.
<link rel="openid.server" href="http://openid.example.com/">
3.2. Submitting a Claimed Identifier
Continuing this example, the End User visits a Consumer site which supports OpenID Authentication. The Consumer presents the End User with a form field for them to enter their Identifier URL.
3.3. Consumer Site Fetches the Identifier URL
Now the Consumer site fetchs the document located at the End User's Claimed Identifier. The Consumer then parses the HEAD section for the "openid.server" and the optional "openid.delegate" declarations.
3.4.1. Important Notes for Smart Mode
  • It's RECOMMENDED that a Consumer first submit an associate request to the End User's Identity Provider and request a shared secret if the Consumer does not already have one cached. This shared secret SHOULD be used as the HMAC-SHA1 key in future identity check requests until it expires.
  • The shared secret can be exchanged either in plain-text or encrypted with a Diffie-Hellman-negotiated secret. Note that if Diffie-Hellman is used, it's only used in the associate mode. The checkid_immediate and checkid_setup modes assume the Consumer already has a shared secret, regardless of how it got it.
3.5. Consumer Verifies the Identifier
The Consumer now constructs a URL to the Identity Provider's checkid_immediate (or checkid_setup) URLs and sends the User-Agent to it.
By sending the User-Agent there, the End User's cookies and whatever other login credentials are sent back to their trusted Identity Provider. The Identity Provider does its work, appends its response onto the supplied openid.return_to URL, and sends the User-Agent back to the Consumer.
4. Modes
4.1. associate
  • Description: Establish a shared secret between Consumer and Identity Provider.
  • HTTP method: POST
  • Flow: Consumer -> IdP -> Consumer
4.1.1. Request Parameters
  • openid.mode
    • Value: "associate"
  • openid.assoc_type
    • Value: Preferred association type
    • Default: "HMAC-SHA1"
  • openid.session_type
    • Value: Blank or "DH-SHA1"
  • openid.dh_consumer_public
    • Value: base64(btwoc(g ^ x mod p))
    • Note: REQUIRED if using DH-SHA1 session_type.
4.1.2. Response Parameters
Response format: Key-Value Pairs
  • assoc_type
    • Value: The association type for the returned handle.
    • Note: The only current mode is HMAC-SHA1, and all Consumers MUST support it. When caching, the Consumer MUST map an assoc_handle to both its secret and its assoc_type.
  • assoc_handle
    • Value: The association handle to be provided in future transactions.
    • Note: Consumers MUST NOT reuse this association handle after the corresponding expires_in value.
  • expires_in
    • Value: The number of seconds this association handle is good for in base10 ASCII.
  • dh_server_public
    • Value: base64(btwoc(g ^ y mod p))
    • Description: The Provider's Diffie-Hellman public key [RFC2631].
  • enc_mac_key
    • Value: base64(SHA1(btwoc(g ^ (xy) mod p)) XOR secret(assoc_handle))
    • Description: The encrypted shared secret.


4.2. checkid_immediate
  • Description: Ask an Identity Provider if a End User owns the Claimed Identifier, getting back an immediate "yes" or "can't say" answer.
  • HTTP method: GET
  • Flow: Consumer -> User-Agent -> IdP -> User-Agent -> Consumer
4.2.1. Request Parameters
  • openid.mode
    • Value: "checkid_immediate"
  • openid.identity
    • Value: Claimed Identifier
  • openid.assoc_handle
    • Value: The assoc_handle from the associate request.
    • Note: Optional; Consumer MUST use check_authentication if an association handle isn't provided or the Identity Provider feels it is invalid.
  • openid.return_to
    • Value: URL where the Provider SHOULD return the User-Agent back to.
4.2.2.2. Sent on Failed Assertion
  • openid.user_setup_url
    • Value: URL to redirect User-Agent to so the End User can do whatever's necessary to fulfill the assertion.
4.2.2.3. Sent on Positive Assertion
  • openid.identity
    • Value: Verified Identifier
  • openid.assoc_handle
    • Value: Opaque association handle being used to find the HMAC key for the signature.
  • [...]
4.2.3. Extra Notes
  • This mode is commonly used for "AJAX"-style setups. The more classic mode to check a Claimed Identifier is checkid_setup.


4.3. checkid_setup
  • Description: Ask an Identity Provider if a End User owns the Claimed Identifier, but be willing to wait for the reply. The Consumer will pass the User-Agent to the Identity Provider for a short period of time which will return either a "yes" or "cancel" answer.
  • HTTP method: GET
  • Flow: Consumer -> User-Agent -> [IdP -> User-Agent ->]+ Consumer
4.2.1. Request Parameters
  • openid.mode
    • Value: "checkid_setup"
  • openid.assoc_handle
  • [the rest are the same as for checkid_immediate]
4.3.2.1. Always Sent
  • openid.mode
    • Value: "id_res" or "cancel"
4.3.2.2. Sent on Positive Assertion
  • [same as for checkid_immediate]


4.4. check_authentication
  • Description: Ask an Identity Provider if a message is valid. For dumb, stateless Consumers or when verifying an invalidate_handle response.
  • HTTP method: POST
  • Flow: Consumer -> IdP -> Consumer
4.4.1. Request Parameters
  • openid.mode
    • Value: "check_authentication"
  • openid.assoc_handle
    • Value: The association handle from checkid_setup or checkid_immediate response.
  • openid.sig
    • Value: The signature from the checkid_setup or checkid_immediate request the Consumer wishes to verify.
  • openid.signed
    • Value: The list of signed fields from the checkid_setup or checkid_immediate request the Consumer wishes to verify the signature of.
4.4.2. Response Parameters
Response format: Key-Value Pairs
  • openid.mode
    • Value: "id_res"
  • is_valid
    • Value: "true" or "false"
    • Description: Boolean; whether the signature is valid.
  • invalidate_handle
    • Value: opaque association handle
    • Description: If present, the Consumer SHOULD uncache the returned association handle.
4.4.3. Extra Notes
  • Identity Providers MUST implement this mode for error recovery and dumb Consumers, which can't keep state locally, but it's RECOMMENDED that it is used as little as possible, as it shouldn't be necessary most the time. It's good for debugging, though, as you develop your Consumer library.


Extensions:

http://openid.net/specs/openid-assertion-quality-extension-1_0-03.html :

This extention to the OpenID Authentication protocol provides means for a Relying Party to request additional information about the specifics by which a user enrolled and/or authenticated to the OpenID Provider, as well as for an OpenID Provider to add such information into assertions. Such information may be necessary for use cases in which, for an RP to make an assesment of the quality of an assertion from a OP, the OP's identity is not on its alone sufficient (as might be the case were an OP capable of authenticating a user through various authentication mechanisms).
The following are properties describing the mechanisms used by the OP policy at the time of enrollment (account creation) and, as such, do not change with each authentication request. In other words, they describe what has already happened, and not a capability for something to happen.
enroll.verified.liveness -- Did the OP present the End User with a liveness during the account creation process?
Value: "captcha", "oob", "other" or "no"
enroll.verified.email -- Did the OP verify any email address the End User provided during the account creation process?
Ads
Personal tools