Forms Authentication 控制流程
Forms Authentication的流程可以参考下图:
我们来分析一下上面的流程:
第一步:用户访问default.aspx页面,IIS通过了验证,ASP.Net发现 authorization
元素中包含<deny users="?" />的标签。
第二步:服务器寻找包含验证信息的cookie,如果没有找到这个cookie,用户将被重定向到登陆页面。就是loginurl所指定的页面。用户将在那个页面输入登陆信息。:
第三步:浏览器请求浏览登录页面,同时传递ReturnUrl的参数的值。
第四步:服务器调转到登陆页面。
第五步:用户输入身份验证信息,并且提交数据,其中还包含ReturnUrl的参数值。
第六部:服务器通过读取存储介质(例如sqserver数据库)验证用户的信息。登陆页面将创建一个包含form authentication ticket的cookie作为session。
在Asp.net2.0身份验证可以通过membership系统。Membership类提供了ValidateUser的方法,参考如下:
if (Membership.ValidateUser(userName.Text, password.Text))
{if (Request.QueryString["ReturnUrl"] != null) {FormsAuthentication.RedirectFromLoginPage(userName.Text,false); }
else { FormsAuthentication.SetAuthCookie(userName.Text, false); } }
else { Response.Write("Invalid UserID and Password");
}
第七步:用户验证成功,服务器重新让浏览器指向ReturUrl所指定的页面。
第八步:在重定向的同时,浏览器向default.aspx页面发送request请求,此次请求包含用户的forms authentication cookie。
第九步:FormsAuthenticationModule类侦测到forms authentication cookie并且开始验证,验证成功后,该类将得到当前的用户信息,并传送给HttpContext对象。可以通过HttpContext对象获得当前用户的信息。
第10步:验证成功,来去自如哦!
FormsAuthenticationModule
ASP.Net 2.0在系统默认的web.config文件中定义了一系列的Http模块(Http Modules).其中包括了一系列的验证模块如下:
<httpModules>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" /> </httpModules>
在每一次请求时,只能使用一种验证模块。通常验证模式会被定义在web.config文件中:
<authentication mode="Forms" />这句话表示使用FormsAuthentication
FormsAuthenticationModule类会创建一个GenericPrincipal的对象,然后把它存入Http Context中。GenericPrincipal包含一个FormsIdentity的实例的引用,FormsIdentity实例包含了用户的信息。一般你会通过forms authentication来替你完成以上工作。但是如果你的程序还有别的特殊要求,比如把用户信息传递给一个自定义的类(该类继承IPrincipal接口),你的程序需要在PostAuthenticate Event事件中编写代码。PostAuthenticate Event事件会在 FormsAuthenticationModule验证forms authentication cookie 并且创建完GenericPrincipal和FormsIdentity对象后触发,在该事件触发后,你可以在事件中创建自定义的IPrincipal对象,用此对象封装FormsIdentity对象,然后把自定义的IPrincipal对象存入HttpContext中。
注意:如果自定义IPricipal对象,你必须在当前线程中设置自定义对象的引用:例如:Thread.CurrentPrincipal=newGenericPrincipal(new GenericIdentity( "Bob"