续上次浅谈了一下passport 的实现。在自己的项目中也进行了运用。
就对于开发中发现的问题进行一下说明。
想达到的目的:
在多个应用系统共享一个用户身份验证系统,而用户在各应用系统中的权限由应用系统自己处理。
主要流程:
应用程序->当用户访问受限页面 -> 由MyPassport 进行身份验证 -> 用户注册 MyPassport 帐号 -> 登录 MyPassport -> 返回应用程序 -> 应用程序得到用户信息 -> 分析角色或权限 -> 访问受限页面
主要的类:
MYPassportAuthentication -- 提供为操作身份验证票提供帮助器实用工具的静态方法
MYPassportAuthenticationModule : IHttpModule - 模块初始化和处置事件
MYPassportAuthenticationEventArgs : EventArgs - 事件参数类
MYPassportAuthenticationTicket - 验证票
MYPassportConfiguration - 配置类
MYPassportConfigurationHandler : IConfigurationSectionHandler - 配置分配
MYPassportIdentity :IIdentity - 用户验证信息 与 HttpContext.User.Identity 统一
有了上面几个类的设计,就可以进行开发了。
我们选用的数据传送方式是:"查询字符串",即"查询字符串" 做为应用程序间 Ticket 信息的信道
当一个应用程序需要登录时,转向MYPassport 的地址是 : http://mypassport.net/login.aspx?appId=11&ru=http://myapplication.com/somepage.aspx
ru为返回应用程序的地址, 其中的 AppId 为应用程序的ID号,用于当ru 信息丢失时使用。
当完成登录:返回应用程序,地址为: http://myapplication.com/somepage.aspx?ticket=%%^^&&(
这里的ticket 为加密后的票,在返回到 应用程序的 MYPassportAuthenticationModule 时,对request.url 进行分析,把ticket 分离出来,
生成真正的 ticket,取得 用户信息,取得权限。完成注册。
一,MYPassportAuthentication 类
由于 Ticket 在网络上传送时,要对数据进行一下加密。等到达应用程序时再进行解密。得到我们想要的票信息。
public static MYPassportAuthenticationTicket Decrypt(string strTicket) // 进行解密
public static string Encrypt(MYPassportAuthenticationTicket ticket) // 加密
这些都是公共的方法,没有什么好说的。
二,MYPassportAuthenticationModule : IHttpModule
注册验证事件与处理
public event MYPassportAuthenticationEventHandler Authenticate;
public void Init(HttpApplication context)
{
context.AuthenticateRequest +=new EventHandler(OnEnter);
context.EndRequest += new EventHandler(this.OnLeave);
}
对ticket 进行处理。
web.config
<httpModules>
<add type="MYCom.Security.KK7PassportAuthenticationModule,MYCom.Security"
name="MYPassport"/>
</httpModules>
三, MYPassportAuthenticationEventArgs
验证事件参数。当发生验证时,取得用户的MYPassportIdentity 信息
四,MYPassportAuthenticationTicket
票,
主要是:用户名,用户基本的信息,与票生成的时间,以及有效期等
五,MYPassportConfiguration 类
mypassport 的配置类,包含了,passport 站点的地址,应用程序的ID号以及用户程序中那些是受限的页面。
六,MYPassportConfigurationHandler 类
internal class MYPassportConfigurationHandler : IConfigurationSectionHandler
{
public virtual object Create(Object parent, Object context, XmlNode node)
{
MYPassportConfiguration config = new MYPassportConfiguration();
try
{
config.LoadValuesFromConfigurationXml(node); //读取配置信息
}
catch
{
throw new Exception("无法读取 Passport 设定!!");
}
return config;
}
}
web.Config 文件:
<configSections>
<sectionGroup name="Passport">
<section name="PassportSettion" type="MYCom.Security.MyPassportConfigurationHandler,MyCom.Security">
</section>
</sectionGroup>
</configSections>
<Passport>
<PassportSettion AppId="2" passportSite="http://mypassport.net/">
<AuthPages>
<location path="/PostArticle.aspx" User="?"></location>
<location path="/PostPoll.aspx" User="?"></location>
<location path="/PostReply.aspx" User="?"></location>
<location path="/myArticles.aspx" User="?"></location>
<location path="/ModifUserInfo.aspx" User="?"></location>
<location path="/AddAttachment.aspx" User="?"></location>
<location path="/Admin/*.aspx" user="?"></location> <!-- admin 目录下的所有后缀为 aspx 的文件受限 /-->
<location path="/DATA/*.*" user="?"></location><!-- data 目录下的所有的文件受限 /-->
</AuthPages>
</PassportSettion>
</Passport>
七,MYPassportIdentity 类
用户的基本信息。
protected void MyPassport_OnAuthenticate(Object sender, MYPassportAuthenticationEventArgs e)
{
// 对用户进行验证
MYPassportIdentity passportIdentity = e.MYPassportIdentity;
string [] roles = null;
if (passportIdentity.IsAuthenticated )
{
roles = getRoles( passportIdentity); //读取用户权限
}
Context.User = new GenericPrincipal( passportIdentity,roles); //生成一般用户
}
这样就基本完成了一个passport 系统的的创建,当然只有这些是远远不够的。还有MYpassport 主站的建设工作,应用程序的注册等。
如有什么问题请与我联系。 ![]()
打印 | 张贴于 2004-04-26 21:47:00 | Tag:ASP.Net C#
留言反馈
可惜细节方面讲的不是很深!
friend
另外考虑到用户注销问题...怎样走流程比较好我也不好说,我自己是采用callback url的机制来实现的,就是在sso端logout页面中完成用户的注销工作同时连到应用的回调地址,然后client端通过httpmodule或者httphandler截获到从而同时处理用户的注销...
现在工作还是比较稳定的,就是有个小问题,java和.net的des算法好象有比较大差异,我在.net的sso端用des算法加密过的数据,无法在java端正确的解开反之也如此...rsa倒是解决了...
望有高手帮助解决...
你的登录状态在哪里保存?如何保证安全性?