2002-09-16 13:31
Hi, 现在我们暂时不谈Passport
在我写了那篇Passport你的网站之后,我发现自己犯了一个错误,从一开始。也许当时只是想表达自己对Passport的喜爱和接触之后还算美好的虚荣感受。我想在当时陶醉时,肯定刻意忽略了其它的某种因素。不然当计划正式开始使用它时,不会发现它突然带有了某种不确定性,甚至退后到测试的机器上也不能工作了;多次再去做和对着文档去想了又想,开始有些惭愧,因为我发现那篇文档几乎毫无用处,这将是一次名不其实表述,那么对于一个技术人员来说,这种感受是痛伤的,同时对他来说也将是个教训。
不过Passport的重要性丝毫不亚于它的复杂和繁琐,无法预知Microsoft将如何改善这种长距离的集中验证所带来的不确定“刺耳音符”,但在未来可以看到的体系和应用中,避而不见Passport,也意味着今后你在MS平台上要冒更多的风险。那么对于“是否需要接触Passport?”、“现在是否需要学习了解Passport?”这样问题的答案都应该是慎重的“应该”,放弃观望的态度将是一个好的开始。我们可以在接触学习中等待3.0版本的Passport,不过在没有更好的Demo,没有我们需要的Help文档的一段时间里,现在我们暂时不谈MS的Passport。它依然复杂得超出我们的理解,我们只能一点点去尝试和了解,做那些我们力所能及的事。最后欢迎回到这个脆弱而迷幻的世界,它依然充满失落和期待。
下面将是一个Passport的实现(我猜是最小的一个框架),它的最初是Nathan Smith (nathan_y_smith@hotmail.com )示范性的一个dotNET β2的版本,调试时我进行了一些小的改动(不少改进吧,但主框架没动),并且添加了一个简单的测试前端。在我升级到dotNET 1.0后,重新测试了它,所以它需要的环境可能是:
Windows 2000 Server, MS SQL 2000 SP2 (中文或英文),dotNET SDK 1.0 , VS.NET RTM,IIS 5.0 SP, IE6 2813
数据结构:
设计两个数据库:PassportSvr , PassportClient
PassportSvr:
PassportClient:
另外还有下面这些实现核心功能的存储过程:
sp_registerUser
sp_setUserInfo
sp_setUserPassword
sp_setUserStatus
sp_purgeUser
sp_setUserHomeService
sp_validateUser
sp_registerService
sp_setServiceInfo
sp_setServicePassword
sp_setServiceStatus
sp_purgeService
sp_validateService
应用实现:
根据上面的数据结构实现了两个Web Services,一个作为整体的Services的管理接口,一个是提供给最终用户使用的Client Services接口。
看得出来最终提供给用户使用的只有7个函数,当然开始时你可以在调试Services WebServices时测试一下RegisterService函数,它将建立一个Services,记下services_name和 services_password ,在实现Client的WebService的Global.cs中有这样应用:
protected void Application_Start(Object sender, EventArgs e)
{
DataManager.InitManager();
Passport ppSvc = new Passport();
AppTicket = ppSvc.AuthenticateService("Passport","passport");
ppSvc=null;
}
整个实现中有个与Passport相似的安全机制-Ticket,当用户通过验证之后获得一个AuthenticationTicket并产生一个Token,我认为这里是最有趣和最棒的部分,简单有效。
Ticket Structure
public class AuthenticationTicket
{
public AuthenticationTicket()
{
}
public int Token;
public int OwnerID;
public double ExpirationDate;
public double IssueDate;
public string NickName;
public string FirstName;
public string LastName;
}
Token Generation Routine
static private int GenerateToken(int systemID, string nickName,
int passwordHash, double issueDate, double expirationDate)
{
int rtn; // our return value
string s_token; // string concatenation of the objects
// concatenate all of our values together.
// note the use of hashing the password and the id, this
// *should* help reduce the probability of attack
s_token=systemID.GetHashCode().ToString() +
nickName + passwordHash.GetHashCode().ToString() +
issueDate.ToString() + expirationDate.ToString();
// get the hash of the concatenation and return it
rtn=s_token.GetHashCode();
return rtn;
}
好了解决了主要问题,后面的实现的就迎刃而解了,下面分别是两个Web Services暴露的功能函数。
public AuthenticationTicket AuthenticateService
public AuthenticationTicket AuthenticateUser
public AuthenticationTicket CreateAccount
public int DisableAccount
public int EnableAccount
public int PurgeAccount
public int SetAccountHome
public int SetAccountInfo
public int SetAccountPassword
public int SetServiceInfo
public int SetServicePassword
public int RegisterService
public bool ValidateServiceTicket
public bool ValidateUserTicket
看得出真正Client端用的接口很简单和明了,(这是又一个不错的亮点)如果一切OK,那么你点击RegisterAccount,输入需要的数据,如果正确那么返回下面的结果:
剩下的工作我想就是包装一下,用一个ASP.NET的Web Form再测试和使用了。
结论:
这将是一个可能的Passport的实现,当然不是全部,但如果不是必须并不建议将其使用在正式的应用中,但你可以从下面的建议中去加强和衍生扩展它:
1. 体系结构上用了最新的Web Services,或许原来的作者太喜欢Web Services了,所以用得可能太多了,那么最可能是在这个例子中你可以看到Web Services事务不完整的现象,当一个We调用时,有时我们会发现只有一个数据库中有数据。
2. 构造实现时使用了SQL 2000的XML特性,尽管向大家展示了SQL 2000的方便特性(Nathan Smith是个MCSD haha),对于要使用Oracle,IBM数据库的需求,也就意味着某种不可移植性,这部分代码必须重新考虑和写过。
3. 作为一个应用的核心功能部分,目前完全的Web Services构架是过于单薄和松散,必须考虑Window Services和线程池的实现来提升性能,同时对程序的构架做一个调整。
4. 数据库设计不完全,需要再细化和重新根据需求进行设计,添加表。记住目前它仅是一个Demo
5. Nathan Smith把数据库的连接放在Goalx的文件中,似乎想节省建立Connection(当然这是一种有些糟糕但是省力的作法),在我测试中发现负责指向第二个数据库连接经常并没有建立,在没有自己实现事务保证的情况下,它往往是数据不完整的主要原因(我已将所有的数据库连接移到了函数内部),所以根据可能需要加入可靠的DAL层。
自从1989年Microsoft从Firefly Network购买Passport之后,Passport在用户数和功能上不断的在发展,1.4版本展示了两个大的功能: Single Sign In (SSI)和Express Purchase(EP).2.0版本主要是提供一个完整的COM接口(很类似WinInet API),内嵌的界面(embedded Passport UI),更重要的是向基于Kerberos 的Authentication迈进。可以预见到未来的2.1或3.0版本,它会增强对IE6、P3P以及WAP、HDML、Microsoft Mobile Explorer、PocketPC等移动设备的支持,更重要的是对基于XML信息处理的支持(目前的Passport的体系结构中Client、 Participating website 和 Microsoft Passport server像一个三角形,在SSI或EP时websit和Passport Server之间并不直接通讯,而是借助Client使用 HTTP查询字符串和 HTTP Redirect来传递信息,所有需要存储的数据比如登录状态、用户Profile是依赖于用户端的cookie),Passport将成为Hailstorm的关键服务,那么对XML的支持是必须的,另外和目前已有的Hailstorm服务之间功能的整合也将是大的挑战,Passport最大的机遇不是推出它的dotNET版本,而且它如何成为一个又是中心化验证,又提供个性化服务的框架,它正式的推出也将是整个Hailstorm(.Net My Services)服务吹响冲锋号角的一个前兆。
无论外界如何评论或是如何和自由联盟争斗,“今天的Passport不等于明天的Passport”(李开复语),未来并不总是一片光明甚至不会一帆风顺。“当我们的路通向一个黑暗的森林,追寻来时的脚步是多么困难。当路被设定好,回归似乎不可能。生命就是我们的契约,除了最高法庭之外,无人能撤销它。”,Passport也是一样:战斗需要更多的炮火,时代早已充满革命,更好的活着是它最超越的荣耀。