使用浏览器后退按钮进行 ASP.NET 身份验证登录和注销
Posted
技术标签:
【中文标题】使用浏览器后退按钮进行 ASP.NET 身份验证登录和注销【英文标题】:ASP.NET authentication login and logout with browser back button 【发布时间】:2011-02-10 19:57:12 【问题描述】:我正在寻找一种解决方案,让用户在注销后使用浏览器的后退按钮导航到上一页。
我在 asp.net 中构建了一个 Web 应用程序,并使用自定义成员资格提供程序进行身份验证和授权。一切正常,除非用户单击注销链接以注销应用程序并重定向到默认封面,如果使用单击浏览器上的 BACK BUTTON,它实际上会回到他们之前的位置并且数据仍会显示。
当然他们不能在那个页面上做任何事情,点击任何链接他们将再次被重定向到登录页面。但是有这些信息显示会让很多用户感到困惑。
我只是想知道是否有什么方法可以清除浏览器的历史记录以使用户无法返回,或者当他们单击后退按钮并让他们重定向到登录页面时。
谢谢
【问题讨论】:
+1 提出一个好问题。 +1 表示好问题,差一点就击败了 -1 表示不好的结论。 那是我的懒惰~会再试一次 【参考方案1】:担心浏览器历史记录和后退按钮会让您头疼和尖锐湿疣。有内置的设施可以解决这个问题。
您的注销链接/按钮应指向包含此代码的页面,以及您想要的任何其他内容。
[vb.net]
Imports System.Web.Security
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
Session.Abandon()
FormsAuthentication.SignOut()
End Sub
[c#]
using System.Web.Security;
private void Page_Load(object sender, System.EventArgs e)
// Put user code to initialize the page here
Session.Abandon();
FormsAuthentication.SignOut();
代码来自这个page 并且是有效的,但是页面很难看。
可以在here 找到关于后退按钮行为的一个很好的问题/答案。
更新:
根据我与 Matthew 的对话,可以使用以下代码在敏感或易变的单个页面上禁用缓存:
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
我很想知道它是否对你有用。
【讨论】:
这不是这个问题的答案。 这是否也会禁用 css/js 的缓存?谢谢:D @Sky Sanders - 等等,你不是在下面的答案中告诉某人 Response.Cache.SetCacheability(HttpCacheability.NoCache) 是他“失去理智了吗?”。不管怎样,我还是喜欢你的回答【参考方案2】:您可以使用 javascript 禁用后退按钮(通常通过将用户发送到转发到另一个页面的页面,以便单击后退让您再次转发)。持久用户仍然可以在历史记录中回溯 2 步并跳过循环。
该页面在浏览器的缓存中。您可以要求浏览器不缓存任何内容,但这会破坏性能,有时甚至会严重影响性能,因此我不建议这样做。
【讨论】:
马修,当有内置功能来解决问题时,为什么要建议破解? Session.Abandon 和 FormsAuthentication.SignOut 不会告诉浏览器清除它的缓存(并且浏览器和中间的代理不必遵守无缓存标头)缓存的页面可以仍然被加载,并且如果在会话被取消后从客户端缓存中的页面发出请求,则不知道结果将是什么,可能是 NullReferenceExceptions,因为页面开始检查会话变量(并重定向到登录页面)。 那么 no-cache 应该在不应该复活的敏感或易失性页面上离散设置。您无法控制客户端并尝试只会增加复杂性。如果他们想在退出后返回 3 次点击进入“页面已过期”.. ?!?!给他们更多的权力。无论如何,我不是在纠缠你只是说...... p.s。使用@sky 确保我收到对 cmets 的回复。 @Sky 如果我有时间我会在明天测试这个,但是当我的应用程序通过安全扫描(大公司的东西)时,代码已经在执行你建议的注销(每个人都应该,不要误会我的意思)。所以它是安全的,但您仍然可以导航回来并查看缓存中的页面。此外,如果您尝试使用缓存中的这些页面之一进行回发,您将被发送到密码页面(因此它是安全的),但在重定向回原始页面时,不知道会话是否会那里。为了使返回和重新发布过时页面变得相当困难,我们禁用了返回按钮。 酷。我添加了用于防止缓存的代码。我主要将它用于 json 处理程序,但应该适用且有效。【参考方案3】:其实我找到了解决方案,我在母版页的页面加载方法中添加了以下sn-p。
Page.Response.Cache.SetCacheability(HttpCacheability.NoCache);
还是谢谢你的回复:)
【讨论】:
嘿,转身,我想你在什么地方失去了理智...... ;-p 这就像试图用大锤修理手表一样。说得好听点,这符合 DWTF 的条件。请重新考虑。【参考方案4】:如果有帮助,您可以尝试使用 HttpResponse.Cache 属性:
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(false);
Response.Cache.VaryByParams["Category"] = true;
if (Response.Cache.VaryByParams["Category"])
//…
或者可以使用 HttpResponse.CacheControl 完全阻止页面缓存,但它已被弃用,取而代之的是上面的 Cache 属性:
Response.CacheControl = “No-Cache”;
或者你真的可以发疯并手动完成所有操作:
Response.ClearHeaders();
Response.AppendHeader(“Cache-Control”, “no-cache”); //HTTP 1.1
Response.AppendHeader(“Cache-Control”, “private”); // HTTP 1.1
Response.AppendHeader(“Cache-Control”, “no-store”); // HTTP 1.1
Response.AppendHeader(“Cache-Control”, “must-revalidate”); // HTTP 1.1
Response.AppendHeader(“Cache-Control”, “max-stale=0″); // HTTP 1.1
Response.AppendHeader(“Cache-Control”, “post-check=0″); // HTTP 1.1
Response.AppendHeader(“Cache-Control”, “pre-check=0″); // HTTP 1.1
Response.AppendHeader(“Pragma”, “no-cache”); // HTTP 1.1
Response.AppendHeader(“Keep-Alive”, “timeout=3, max=993″); // HTTP 1.1
Response.AppendHeader(“Expires”, “Mon, 26 Jul 1997 05:00:00 GMT”); // HTTP 1.1
Reference
【讨论】:
【参考方案5】:这段代码很有用
Response.Cache.SetCacheability(HttpCacheability.NoCache);
仅将此代码放在加载事件上,以防万一,但它仅适用于 IE,适用于我使用的 IE 和 Firefox
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
【讨论】:
【参考方案6】:Your Answer
解决方法是将以下 javascript 代码添加到 logout.aspx 页面的部分:
<script type="text/javascript">
window.history.forward(1);
</script>
如果用户通过按返回按钮进入注销页面,此 javascript 代码会将用户返回。
如果您需要确保用户在注销后无法返回页面,则必须通过在每个页面上包含类似于以下的代码来要求浏览器不要缓存任何页面:
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
【讨论】:
【参考方案7】:最好的解决方法是将以下代码放在您的母版页中。它避免了缓存页面并阻止用户在注销后访问它。
P.S : 以下代码是从各种来源编译的。将其发布在这里,以便任何寻找解决方案的人都可能会发现它很有用
Master.cs
protected void Page_Load(object sender, EventArgs e)
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Master.aspx
<a href="logout.aspx">Logout</span></a>
注销.cs
protected void Timer1_Tick(object sender, EventArgs e)
Session.Clear();
Session.Abandon();
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
try
Session.Abandon();
FormsAuthentication.SignOut();
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Buffer = true;
Response.ExpiresAbsolute = DateTime.Now.AddDays(-1d);
Response.Expires = -1000;
Response.CacheControl = "no-cache";
//Response.Redirect("login.aspx", true);
catch (Exception ex)
Response.Write(ex.Message);
Response.Redirect("Signin.aspx");
注销.aspx
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" Text="Loggin Out Please Wait" runat="server" />
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick">
</asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</form>
【讨论】:
以上是关于使用浏览器后退按钮进行 ASP.NET 身份验证登录和注销的主要内容,如果未能解决你的问题,请参考以下文章
点击浏览器后退按钮时如何刷新 ASP .NET MVC 页面
使用 ADFS 对 ASP.NET Web Api 进行身份验证