问题描述:
ASP.NET使用表单验证在注销后浏览器仍然可以通过后退按钮回退到之前需要sign in才能看到的页面。
问题原因:
页面还保存在浏览器缓存中
解决方案:
一个可行的方案是为网站增加一个Exit.aspx页面,在其Page_Load方法里执行FormsAuthentication.SignOut(),同时使用JavaScript跳转到Logon页面。而SignOut按钮的唯一作用就是在客户端跳转到该Exit.aspx页面,而不是直接执行FormsAuthentication.SignOut():
1. Web.config如下,指明authentication方式为forms,loginUrl为logon.aspx。拒绝一切未授权用户("?")
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="logon.aspx" name=".ASPXFORMSAUTH">
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
2. Logog.aspx页面如下:
<% @ Import Namespace = " System.Web.Security " %>
< script runat = " server " >
void Logon_Click( object sender, EventArgs e)
{
if ((UserName.Text == " testuser " ) &&
(UserPass.Text == " testuser " ))
{
FormsAuthentication.RedirectFromLoginPage
(UserName.Text, Persist.Checked);
}
else
{
Msg.Text = " Invalid credentials. Please try again. " ;
}
}
</ script >
< html >
< head id = " Head1 " runat = " server " >
< title > Forms Authentication - Login </ title >
</ head >
< body >
< form id = " form1 " runat = " server " >
< h3 >
Logon Page </ h3 >
< table >
< tr >
< td >
E - mail address: </ td >
< td >
< asp:TextBox ID = " UserName " runat = " server " /></ td >
< td >
< asp:RequiredFieldValidator ID = " RequiredFieldValidator1 "
ControlToValidate = " UserName "
Display = " Dynamic "
ErrorMessage = " Cannot be empty. "
runat = " server " />
</ td >
</ tr >
< tr >
< td >
Password: </ td >
< td >
< asp:TextBox ID = " UserPass " TextMode = " Password "
runat = " server " />
</ td >
< td >
< asp:RequiredFieldValidator ID = " RequiredFieldValidator2 "
ControlToValidate = " UserPass "
ErrorMessage = " Cannot be empty. "
runat = " server " />
</ td >
</ tr >
< tr >
< td >
Remember me ?</ td >
< td >
< asp:CheckBox ID = " Persist " runat = " server " /></ td >
</ tr >
</ table >
< asp:Button ID = " Submit1 " OnClick = " Logon_Click " Text = " Log On "
runat = " server " />
< p >
< asp:Label ID = " Msg " ForeColor = " red " runat = " server " />
</ p >
</ form >
</ body >
</ html >
3. Default.aspx页面如下:
< html >
< head >
< title > Forms Authentication - Default Page </ title >
</ head >
< script runat = " server " type = " text/C# " >
void Page_Load( object sender, EventArgs e)
{
Welcome.Text = " Hello, " + Context.User.Identity.Name;
}
</ script >
< body >
< h3 >
Using Forms Authentication
</ h3 >
< asp:Label ID = " Welcome " runat = " server " />
< form id = " Form1 " runat = " server " >
< input type = " button " onclick = " window.location='Exit.aspx' "
value = " Sign Out " />
</ form >
</ body >
</ html >
可见这里的SignOUt按钮是客户端控件,作用是跳转到Exit.aspx进行注销。由于这里使用的是Window.location跳转,所以在logon.aspx页面后退时,将会后退到exit.aspx而不是default.aspx
4. Exit.aspx:
< html >
< head >
< title ></ title >
</ head >
< script type = " text/javascript " >
top.location.href = " Logon.aspx " ;
</ script >
< script runat = " server " type = " text/C# " >
void Page_Load( object sender, EventArgs e)
{
FormsAuthentication.SignOut();
}
</ script >
< body >
</ body >
</ html >
可见,只要用户尝试从logon.aspx回退,都会在这里又重新返回logon.aspx。
当然还有一种更保险的方法,就是在客户log out以后,直接将浏览器关闭: