Scott Hanselman

The Weekly Source Code 25 - OpenID Edition

April 30, '08 Comments [161] Posted in ASP.NET | ASP.NET MVC | DasBlog | Identity | Source Code
Sponsored By

OpenID Logo We spent a lot of time at Corillian (my last job) thinking about Identity, and a few months before I left I started getting into Cardspace and OpenID. This was a little over a year ago. We did a podcast on OpenID as well.

At that time, I tried to take the only .NET implementation at the time of OpenID which was written in in Boo written originally by Grant Monroe and port it to C# causing me to go through the Programmer Phases of Grief. Andrew Arnott and Jason Alexander took the reins and we spend a number of late nights trying to get a good OpenID library working. I gave up, but they soldiered on and created dotnetopenid (downloads), including a client and server as well as Andrew's excellent ASP.NET controls .

Fast-forward to now. My new friend Aaron Hockley decided to a stands and promote OpenID. He said:

Effective immediately, I will no longer comment on tech blogs that don’t support OpenID for comment authentication.

He's just one guy, but his heart is in the right place. He points out that:

Google offers it as a Blogger option. It’s available as a super-easy-to-install WordPress plugin. Movable Type has it as a built-in feature.

OpenID is a good thing and it's Growing. You may already have an OpenID if, for example, you have a Yahoo! account. More on this soon.

How to turn your blog into an OpenID

Simon Willison wrote How to turn your blog into an OpenID and it's very easy.

STEP 1: Get an OpenID. There a lots of servers and services out there you can use. I use http://www.myopenid.com for two reasons. One, I know the CEO (they're in Portland), and two, they support optionally using CardSpace to authenticate yourself (as well as the standard way with password).

STEP 2: Add these two lines to your blog's main template in-between the <HEAD></HEAD> tags at the top of your template. Most all blog engines support editing your template so this should be an easy and very possible thing to do.

Example:

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

This will let you use your domain/blog  as your OpenID. Now, I can log in with "http://www.hanselman.com" when I see an OpenID Login option - and so can you! Go do it now!

Making OpenID Logins Easier

If you have a blog or site with OpenID support, you should go get this little snippet of JavaScript and install an OpenID ID Selector on your blog from http://www.idselector.com/.

virgin-3

One of the things that is slowing OpenID adoption is that many people don't realize that they may already have one. That's what this little Javascript is trying to do by showing folks sites that they recognize. This way my Dad could login using Yahoo and it would make sense to him. It's a little busy, but it's a start. I've added an http://www.idselector.com/ to my blog for comments.

Adding OpenID Support to DasBlog

A year ago, I originally tried to port the Boo code to C# in an attempt to enable OpenID in DasBlog but eventually gave up. However, last night, I re-familiarized myself with the OpenID spec (it's on 2.0 now) and started reading the source for http://code.google.com/p/dotnetopenid/.

In a word, it's a joy. I was able to get OpenID running OK in two hours and working well and up on my blog in two more. I have to give credit to the fantastic work that Andrew Arnott and Jason Alexander and team are doing. It's come far and you should know about it, Dear Reader.

I had two scenarios in DasBlog (again, in case you didn't know, it's the C# and XML-based blog that runs this site and others) to handle.

First, I wanted to support OpenID for Comments which wouldn't actually "log a user in" in the stateful FormsAuthentication sense. I think this isn't a very common scenario, and I'd describe it as One-Time Occasional Authentication. In this case, I used the dotnetopenid classes directly in a moderately complex scenario.

Second, I wanted to support OpenID to login as the Administrator for my site. This would, in fact, log me in via FormsAuthentication. This would be a common scenario that you'd probably care about as it's very typical. In this case, I used the dotnetopenid ASP.NET Controls, which were about as easy as falling off a log. (That's pretty easy.)

Here's the first, harder, scenario.

If you've entered your OpenID and hit Submit Comment then we'll store the current entry and the comment you're submitting. We'll be redirecting away to get authenticated and we'll need them when we get back. If you're running in a WebFarm, you'll want to store these temporary variables in a database or somewhere that doesn't have node-affinity.

Session["pendingComment"] = comment.Text;
Session["pendingEntryId"] = ViewState["entryId"] as string;
OpenIdRelyingParty openid = new OpenIdRelyingParty();
IAuthenticationRequest req = openid.CreateRequest(openid_identifier.Text);
ClaimsRequest fetch = new ClaimsRequest();
fetch.Email = DemandLevel.Require;
fetch.Nickname = DemandLevel.Require;
req.AddExtension(fetch);
SaveCookies();
req.RedirectToProvider();
return;

What I think of as an "OpenID Client" is called a "Relying Party" or "RP" in the parlance of the OpenID folks. In this code we create an AuthenticationRequest and add some additional claims. There's a nice interface-based extension model in this lower-level library that lets you Request or Require information from the user's profile. For comments on the blog, I just need your email for your Gravatar and your Nickname for Display.

I then call RedirectToProvider, and that's if for the request side. Remember I said this was the hard scenario! Not so hard. ;)

Next, we're redirected to an OpenIDProvider, we authenticate (or not) and are redirected BACK with additional information encoded on the GET. On the way back in, in our Page_Load (or an HttpHandler if you like) we check the Response status.  If we're Authenticated, we grab the info we requested and add the comment. Bam. Sprinkle in a little error handling and we're all set.

OpenIdRelyingParty openid = new OpenIdRelyingParty();
if (openid.Response != null)
{
// Stage 3: OpenID Provider sending assertion response
switch (openid.Response.Status)
{
case AuthenticationStatus.Authenticated:
ClaimsResponse fetch = openid.Response.GetExtension(typeof(ClaimsResponse)) as ClaimsResponse;
string nick = fetch.Nickname;
string homepage = openid.Response.ClaimedIdentifier;
string email = fetch.Email;
string comment = Session["pendingComment"] as string;
string entryId = Session["pendingEntryId"] as string;
if (String.IsNullOrEmpty(comment) == false && String.IsNullOrEmpty(entryId) == false)
{
AddNewComment(nick, email, homepage, comment, entryId, true);
}
break;
}
}

Here's the second scenario where we'll log in as the Administrator of the blog. I just register the DotNetOpenId assembly in my ASPX page and put an <openidlogin> control on the page. Notice that even the claims I created in the manual scenario above are just properties on this control. There's also events like OnLoggedIn to handle the results.

<%@ Register Assembly="DotNetOpenId" Namespace="DotNetOpenId.RelyingParty" TagPrefix="cc1" %>
<cc1:openidlogin id="OpenIdLogin1"
RequestEmail="Require" RequestNickname="Request" RegisterVisible="false"
RememberMeVisible="True" PolicyUrl="~/PrivacyPolicy.aspx" TabIndex="1"
OnLoggedIn="OpenIdLogin1_LoggedIn"/></cc1:openidlogin>

This controls renders nicely as seen in the screenshot below.

image

In the OnLoggedIn event, I call my existing security APIs (Thanks to Tony Bunce and Anthony Bouch) and set the AuthCookie from FormsAuthentication.

protected void OpenIdLogin1_LoggedIn(object sender, OpenIdEventArgs e)
{
UserToken token = SiteSecurity.Login(e.Response);
if (token != null)
{
FormsAuthentication.SetAuthCookie(userName, rememberCheckbox.Checked);
Response.Redirect(SiteUtilities.GetAdminPageUrl(), true);
}
}

Poof. I love using well designed libraries and just work. At this point all that was left was adding some CSS and tidying up.

OpenID and ASP.NET WebForms and MVC

The dotnetopenid source includes source for sample sites. It actually includes three samples, two WebForms and one ASP.NET MVC.

The MVC implementation is very clean, even though (or because?) it doesn't use controls. Here's the Authenticate Controller Action:

public void Authenticate() {
var openid = new OpenIdRelyingParty();
if (openid.Response == null) {
// Stage 2: user submitting Identifier
openid.CreateRequest(Request.Form["openid_identifier"]).RedirectToProvider();
} else {
// Stage 3: OpenID Provider sending assertion response
switch (openid.Response.Status) {
case AuthenticationStatus.Authenticated:
FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false);
break;
case AuthenticationStatus.Canceled:
ViewData["Message"] = "Canceled at provider";
RenderView("Login");
break;
case AuthenticationStatus.Failed:
ViewData["Message"] = openid.Response.Exception.Message;
RenderView("Login");
break;
}
}
}

What about CardSpace?

Infocard LogoOpenID is a spec for a protocol that "eliminates the need for multiple usernames across different websites, simplifying your online experience."  What's cool is that it's open, so you (the consumer) gets to pick your Provider. It's not owned by anyone, so it's ours to screw up (or succeed with).

CardSpace is built into Vista and installed on XP when you put .NET 3.0 on your system. There are also Identity Selectors for Safari and Firefox in the works. It's different than OpenID in that it's concerned with strong authentication. Therefore, they are very complimentary.

Here's my CardSpace login as I'm getting ready to log into this blog...

image

...because my chosen OpenID provider at http://www.myopenid.com (it's free) also supports both InfoCards and SSL Certificates for authentication as well as strong passwords.

Notice the "Sign into Information Card" icon below next to the IconCard purple icon.

image

An OpenID provider can choose to use anything available with which to authenticate you. Here's a video of a Belgian using an eID to authenticate against an OpenID provider at http://openid.trustbearer.com/ that supports biometric devices, USB keys, and smart cards.

So What?

Get involved and give it a try! Here's some things you can do.

  1. Sign up for a Free OpenID at MyOpenID or one of the many public OpenID providers out there.
  2. Go use your new OpenID at one of the many sites that supports OpenID.
    • Come back to this post and leave your first comment using OpenID!
  3. Watch Simon Willison talk about the case for OpenID (video)

And, if you're a developer, get an OpenID library like dotnetopenid and consider enabling your app. Consider using the Javascript ID Selector to make for a nicer User Experience.

Technorati Tags: ,,

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Hanselminutes Podcast 50 - OpenID/Microsoft Announcement

February 9, '07 Comments [1] Posted in Identity | Podcast
Sponsored By

My fiftieth podcast is up. This one was about the OpenID/Microsoft Annoucement and how OpenID will affect Identity 2.0 possibly more than CardSpace - certainly in the short term.

ACTION: Please vote for us on Podcast Alley!

Links from the Show

My OpenID (lu2)
ZDNET on the Announcement (lu7)
OpenID Screencast (lu3)
Historical Background (lu8)
Notes on Bill Gates’ Identity Keynote (luc)
OpenID Explained (lu4)
CardSpace / OpenID Collaboration Announcement (lu9)
TailRank on OpenID (lud)
Identity 1.0 (lu5)
Scott Kveton on CardSpace and OpenID (lua)
Integrating OpenID and Infocard - Part 1 (lue)
OpenID Commentary (lu6)

Subscribe: Feed-icon-16x16 Subscribe to my Podcast in iTunes

Do also remember the archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Our sponsors are /n software and the .NET Dev Journal.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

  • The basic MP3 feed is here, and the iPod friendly one is here. There's a number of other ways you can get it (streaming, straight download, etc) that are all up on the site just below the fold. I use iTunes, myself, to listen to most podcasts, but I also use FeedDemon and it's built in support.
  • Note that for now, because of bandwidth constraints, the feeds always have just the current show. If you want to get an old show (and because many Podcasting Clients aren't smart enough to not download the file more than once) you can always find them at http://www.hanselminutes.com.
  • I have, and will, also include the enclosures to this feed you're reading, so if you're already subscribed to ComputerZen and you're not interested in cluttering your life with another feed, you have the choice to get the 'cast as well.
  • If there's a topic you'd like to hear, perhaps one that is better spoken than presented on a blog, or a great tool you can't live without, contact me and I'll get it in the queue!

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Corillian, CardSpace, and Open ID - Digital Identity is happening

February 7, '07 Comments [4] Posted in Corillian | Identity
Sponsored By

I totally stole the picture at right from Ashish Jain's blog post on CardSpace/OpenID Integration. It's a great image. Ashish works for PingIdentity and is down at the RSA Conference right now, along with Corillian it turns out. Ping is demonstrating a prototype OpenID IdP server that uses CardSpace for authentication at runtime.

Today JanRain, SXIP, Verisign and Microsoft announced that they'd collaborate on interoperability between OpenID and CardSpace. It's so refreshing to see folks in Web 2.0 getting along so well and moving the ball forward.

While some are surprised that folks are actually getting along, Dare puts it best when he says:

"With OpenID it didn't take as long for us to go through the NIH<->FUD<->Acceptance<->Approval<->Adoption cycle that I've come to expect from my fellow B0rg. It seems we have adapted."

Corillian (my company) was involved in the Identity Press Release today as well with a joint demo between Corillian, Wachovia and Arcot, led on the Corillian side by the tireless Stuart Celarier.

To further enable the vision of secure and easy anywhere access, Microsoft today announced the following product milestones and industry alliances:
...
On the heels of the Windows® CardSpace™ general availability launch in Windows Vista™, Microsoft demonstrated momentum with industry partners that are working to apply this technology to help consumers realize a more confident online experience. This includes the announcement of collaboration on use of Windows CardSpace with the OpenID 2.0 specification. Through the support of the WS-Trust-based Windows CardSpace experience, consumers can take advantage of increased security against phishing attacks without adding complexity to their identity management experience. Also at the conference, Wachovia Corp., Arcot Systems Inc. and Corillian Corp. showcased a proof of concept demonstration using Windows CardSpace to deliver a simpler and safer online banking experience for customers.

We've been looking at Digital Identity 2.0 solutions for at least 2 years now at Corillian led in part by our multi-factor authentication product and other identity solutions, all designed to stop phishing. We've integrated our suite with CardSpace, and that's what we're demoing at RSA. OpenID was next on my list. If you're not familiar, OpenID is different from CardSpace, as explained by Kim Cameron in that it assumes two things:

  1. Every person has a URL to which they lay claim.
  2. Every URL has an identity provider that “speaks for” it.

He summarizes:

"All in all, the closest analogy is to using an email address as an identifier by asking what email address you own, sending you the email, and getting you to click a link showing you own the email.  In this case the relying party depends on the underlying mail system, DNS, and all that.  OpenID replaces email with web URLs.  So it’s a lot more direct."

Digital Identity is getting closer with InfoCard/CardSpace, OpenID and i-names starting to converge on something very real. Here's some fun links to check out for yourself:

OpenID and CardSpace together are going to cover the maximum number of platforms, the maximum number of browsers and make the end-user experience (like my Mom's) more secure and easier to use that ever before. I'm stoked that Corillian's involved in the banking back-end side of things with folks like Arcot and Wachovia and I'm jazzed to be architecting, in a small way - along with my fellow wonks here at Cori - something called Banking 2.0. I'm looking forward to logging into a Corillian bank using OpenID and/or CardSpace. If you're down in SFO at the RSA Conference, go see our InfoCard Banking Demonstration!

Also, one of these days we'll get another DasBlog release that includes Kevin Hammond's good CardSpace work as well as OpenID. It's only a matter of doing it. You can also CardSpace-enable Community Server if you like.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Page 1 of 1 in the Identity category

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.