每周源代码25——OpenID版
[原文发表地址] The Weekly Source Code 25 - OpenID Edition
[原文发表时间] 2008-04-30 7:11 AM
我在Corillian(我的上一份工作)花了很多时间琢磨Identity. 在离开的前几个月,我开始着手研究Cardspace 和 OpenID。这都是一年前的事了。我们还制作一个关于OpenID的播客。
当时,在最初是由Grant Monroe 用Boo编写OpenID的时候,我试图先只采取.NET来实现。然后再将其移植到C#中,这使我经历了痛苦的几个编程阶段。Andrew Arnott和 Jason Alexander充满激情,为此,我们数个晚上都工作到深夜,试图开发一个非常棒的OpenID库。最后,我放弃了,但他俩却迎难而上,创建了dotnetopenid(下载),其中包括一个客户端、服务器和Andrew开发的非常棒的ASP.NET控件。
时间飞逝啊!再看看现在,我的新朋友Aaron Hockley决定支持并推广OpenID。他说到:
“从现在开始,如果留言板不支持OpenID,我将不会再评论科技博客。”
他就是这样一个人,但不可否认,他是个好心人, 他指出:
“谷歌把它作为一个Blogger选项。它被用作为一个超级易于安装的WordPress插件。Movable Type将其作为内置功能。
OpenID 是一项不断发展的好技术。你可能已经有一个OpenID了,例如,你有一个Yahoo!帐户,接着你可以在更多的地方使用到这个帐号。
怎样将你的博客转换成一个OpenID呢?
Simon Willison 写了一篇《关于如何将你的博客转换成OpenID》的文章,内容其实很简单。
步骤一:获得一个OpenID。有大量的服务器和服务可以使用。我使用https://www.myopenid.com 的原因有两个。第一,我认识该网站的CEO(他们在波特兰);第二,他们支持有选择性地使用CardSpace进行身份验证(和密码验证的标准方法差不多)。
步骤二: 将这两行添加到您博客的主要模板顶部的<HEAD></HEAD>标签之间。几乎所有的博格引擎都支持模板编辑,所以这应该非常简单,可行性强。
例如:
1: <link rel="openid.server" href="https://www.myopenid.com/server" />
2: <linkrel="openid.delegate" href=https://YOURUSERNAME.myopenid.com/ />
这样,就可将您的域名/博客 作为OpenID。 现在,当我登陆https://www.hanselman.com时,就可以看到OpenID登录选项了。你也可以的!现在就试试吧!
让OpenID登录更简单
如果你有一个博客或网站支持OpenID,你应该可以获取这个小的JavaScript代码段,并从 https://www.idselector.com/ 上安装一个OpenID ID选择器到你的博客上。
减缓使用OpenID技术的一个原因是:很多人不知道自己原本就有一个OpenID。这就是这个小小的Javascript代码段正尝试去做的事,通过向大家展示大家所熟识的网站。通过此方法,我爸爸也可以通过Yahoo来登陆,这给他带来了帮助。虽然有点小麻烦,但这是个不错的开端。我添加了https://www.idselector.com/ 到我的博客中以供大家评论。
对DasBlog添加OpenID支持
一年前,我原本打算将Boo代码移植到C#中,以使OpenID 能在DasBlog上使用,但最终还是放弃了。然而,昨晚,我又重新熟悉了 OpenID 特性(它现在是2.0版本了),并开始阅读https://code.google.com/p/dotnetopenid/源代码。
总之,蛮有乐趣的。我能在两小时内使OpenID正常运行起来,并在另外两个博客上也起作用。我不得不对Andrew Arnott、Jason Alexander和他们整个团队所做的令人难以置信的工作表示赞赏。话说回来,亲爱的读者,你应该知道:
我在DasBlog(如果你不清楚,我再说一遍,它是运行于此网站或其他网站的基于C#和XML的博客)上有两种方案。
首先,我想让留言板支持OpenID。而且它并会在FormsAuthentication上呈现“以用户登入”状态。我认为这不是一个常用方案,我把它描述为“一次性临时身份验证”,在这个例子中,我在一个中等复杂的方案下直接使用了dotnetopenid类。
其次, 我想支持OpenID作为管理员身份来登录我的网站。事实上,这将通过FormsAuthentication登录。 你可能会关心这个通常的方案,因为它非常典型的。在这个例子中,我使用dotnetopenid ASP.NET控件,它和取消登陆一样简单 (这是很容易的) 。
这里是第一个比较难的方案
如果您输入您的OpenID,并点击Submit Comment,那么我们将保存当前条目及您提交的评论。我们将再次要求去获得验证。返回的时候还要用到它们。如果你在WebFarm上运行,你要将这些临时变量存储在没有node-affinit的数据库或某个地方。
1: Session["pendingComment"] = comment.Text;
2: Session["pendingEntryId"] = ViewState["entryId"] as string;
3: OpenIdRelyingParty openid = new OpenIdRelyingParty();
4: IAuthenticationRequest req = openid.CreateRequest(openid_identifier.Text);
5: ClaimsRequest fetch = new ClaimsRequest();
6: fetch.Email = DemandLevel.Require;
7: fetch.Nickname = DemandLevel.Require;
8: req.AddExtension(fetch);SaveCookies();
9: req.RedirectToProvider();
10: return;
据OpenID人士所称,我所认为的“OpenID客户端” 其实被称作”Relying Party”或简称为 “RP”。在此代码中,我们创建了一个AuthenticationRequest并添加一些额外的声明。 在这个低级别的库中有一个友好的基于接口的扩展模型。它使得您可以从用户的个人资料信息中Request或Require信息。 在博客的评论中,我只需要您的Gravatar电子邮件,并显示您的昵称。
然后,调用RedirectToProvider,这是请求方应该做的。记得我前面讲过这是个很难的方案!其实也没那么难。;)
下一步,我们重新转向一个OpenIDProvider,我们进行身份验证(不验证也可以),然后和在GET上编码的其他信息一起传回。在返回的过程中,在Page_Load(或HttpHandler)检查响应状态。 如果验证完毕,我们攫取要求的信息并添加注释。Bam. Sprinkle处理一个小错误,然后我们就全部就绪了。
1: OpenIdRelyingParty openid = new OpenIdRelyingParty();
2: if (openid.Response != null)
3: { // Stage 3: OpenID Provider sending assertion response
4: switch (openid.Response.Status)
5: {
6: case AuthenticationStatus.Authenticated:
7: ClaimsResponse fetch = openid.Response.GetExtension(typeof(ClaimsResponse)) as ClaimsResponse;
8: string nick = fetch.Nickname;
9: string homepage = openid.Response.ClaimedIdentifier;
10: string email = fetch.Email;
11: string comment = Session["pendingComment"] as string;
12: string entryId = Session["pendingEntryId"] as string;
13: if (String.IsNullOrEmpty(comment) == false && String.IsNullOrEmpty(entryId) == false)
14: {
15: AddNewComment(nick, email, homepage, comment, entryId, true);
16: }
17: break;
18: }
19: }
下面是第二种方案,我们将以博客管理员身份登陆。我只需在ASPX页面注册一个DotNetOpenId组件,并将<openidlogin>控件置于页面上就行了。请注意,甚至我在上面的手动的情况下创建的声明也仅仅是此控件的属性。还有些像OnLoggedIn的事件可以处理结果。
1: <%@ Register Assembly="DotNetOpenId" Namespace="DotNetOpenId.RelyingParty" TagPrefix="cc1" %>
2: <cc1:openidlogin id="OpenIdLogin1" <br cssclass="openidLogin" runat="server">RequestEmail="Require" RequestNickname="Request" RegisterVisible="false"
3: RememberMeVisible="True" PolicyUrl="~/PrivacyPolicy.aspx" TabIndex="1"
4: OnLoggedIn="OpenIdLogin1_LoggedIn"/></cc1:openidlogin>
下面的截图很好地呈现了该控件。
在OnLoggedIn事件中,我调用现有安全APIs(多亏了Tony Bunce和Anthony Bouch),并在FormsAuthentication上设置了AuthCookie.
1: protected void OpenIdLogin1_LoggedIn(object sender, OpenIdEventArgs e)
2: {
3: UserToken token = SiteSecurity.Login(e.Response);
4: if (token != null)
5: {
6: FormsAuthentication.SetAuthCookie(userName, rememberCheckbox.Checked);
7: Response.Redirect(SiteUtilities.GetAdminPageUrl(), true);
8: }
9: }
喔哟,我喜欢使用精心设计的库。在此时,剩下要做的就是添加一些CSS,并进行整理。
OpenID , ASP.NET WebForms 以及 MVC
dotnetopenid 源包括样本网站的资源。它实际上包括三个样本,两个WebForm以及一个ASP.NET MVC。
MVC的执行是
1: public void Authenticate() {
2: var openid = new OpenIdRelyingParty();
3: if (openid.Response == null) {
4: // Stage 2: user submitting Identifier
5: openid.CreateRequest(Request.Form["openid_identifier"]).RedirectToProvider();
6: } else {
7: // Stage 3: OpenID Provider sending assertion response
8: switch (openid.Response.Status) {
9: case AuthenticationStatus.Authenticated:
10: FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false);
11: break;
12: case AuthenticationStatus.Canceled:
13: ViewData["Message"] = "Canceled at provider";
14: RenderView("Login");
15: break;
16: case AuthenticationStatus.Failed:
17: ViewData["Message"] = openid.Response.Exception.Message;
18: RenderView("Login");
19: break;
20: }
21: }
22: }
CardSpace怎么样呢?
OpenID是一个规范的协议:“免去了在不同网站使用不同帐号的麻烦,简化您的在线体验。” 最酷的是它具有开放性,你(用户)可以任意选择提供方。所以,要么搞砸,要么成功,我们自己说了算。
如果你将NET 3.0放在系统上的话,CardSpace是内置于Vista和XP系统中的。 里面也有针对Safari 和 Firefox的Identity Selectors。它跟OpenID的不同之处在于,它与强身份验证有关。 因此,他们是互补的。
这里是我的CardSpace登录界面,我准备登录到这个博客... ...
因为我选择的OpenID 提供商 是https://www.myopenid.com(免费的),也支持InfoCard和SSL证书认证以及强度密码。
请注意下面 IconCard紫色图标旁边的“Sign into Information Card”图标。
一个OpenID供应商可以选择使用任何可用的东西对您进行验证。这里有一个 比利时人使用EDI 通过一个OpenID提供商进行身份验证的视频,这个OpenID提供商是https://openid.trustbearer.com/,它支持生物识别设备,USB钥匙和智能卡。
那么,该怎么做呢?
参与进来试试吧!你可以按照下列步骤操作。
在 MyOpenID或在许多公共OpenID 提供商中注册一个免费的OpenID。
- 然后,将你自己的域名或博客变成 OpenID。
在其中某个支持OpenID的网站中使用您的新OpenID。
- 再回到这个帖子处, 使用OpenID来发布你的第一条评论。
观看SimonWillison 谈论关于OpenID的案例 ( 视频 )
如果你是开发人员,获取一个诸如dotnetopenid的OpenID库,并考虑在你的应用程序中使用它。同时考虑使用Javascript ID Selector来创造一个更好的用户体验。