Jas*_*son 139 asp.net forms-authentication
对此我砸了太久了.如何防止用户在使用FormsAuthentication.SignOut注销后浏览网站的页面?我希望这样做:
FormsAuthentication.SignOut();
Session.Abandon();
FormsAuthentication.RedirectToLoginPage();
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.如果我直接输入URL,我仍然可以浏览到该页面.我有一段时间没有使用自己的安全性,所以我忘记了为什么这不起作用.
Igo*_*mić 202
用户仍然可以浏览您的网站,因为在您拨打电话时不会清除Cookie,FormsAuthentication.SignOut()
并且每次新请求都会对其进行身份验证.在MS文档中说cookie将被清除,但它们没有,bug?与它完全相同Session.Abandon()
,cookie仍然存在.
您应该将代码更改为:
FormsAuthentication.SignOut();
Session.Abandon();
// clear authentication cookie
HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, "");
cookie1.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie1);
// clear session cookie (not necessary for your current problem but i would recommend you do it anyway)
SessionStateSection sessionStateSection = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState");
HttpCookie cookie2 = new HttpCookie(sessionStateSection.CookieName, "");
cookie2.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie2);
FormsAuthentication.RedirectToLoginPage();
Run Code Online (Sandbox Code Playgroud)
HttpCookie
在System.Web
命名空间中.MSDN参考.
jwa*_*rjr 20
听起来像你没有正确设置你的web.config授权部分.请参阅下面的示例.
<authentication mode="Forms">
<forms name="MyCookie" loginUrl="Login.aspx" protection="All" timeout="90" slidingExpiration="true"></forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
Run Code Online (Sandbox Code Playgroud)
jus*_*n23 20
使用x64igor和Phil Haselden的上述两个帖子解决了这个问题:
1. x64igor举例说明了注销:
首先需要通过将响应中的空cookie传回注销来清除身份验证Cookie和会话Cookie.
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
Session.Clear(); // This may not be needed -- but can't hurt
Session.Abandon();
// Clear authentication cookie
HttpCookie rFormsCookie = new HttpCookie( FormsAuthentication.FormsCookieName, "" );
rFormsCookie.Expires = DateTime.Now.AddYears( -1 );
Response.Cookies.Add( rFormsCookie );
// Clear session cookie
HttpCookie rSessionCookie = new HttpCookie( "ASP.NET_SessionId", "" );
rSessionCookie.Expires = DateTime.Now.AddYears( -1 );
Response.Cookies.Add( rSessionCookie );
Run Code Online (Sandbox Code Playgroud)2. Phil Haselden上面举例说明了如何在注销后阻止缓存:
您需要通过响应使客户端上的缓存无效.
// Invalidate the Cache on the Client Side
Response.Cache.SetCacheability( HttpCacheability.NoCache );
Response.Cache.SetNoStore();
// Redirect to the Home Page (that should be intercepted and redirected to the Login Page first)
return RedirectToAction( "Index", "Home" );
}
Run Code Online (Sandbox Code Playgroud)Phi*_*den 12
这里的关键是你说"如果我直接输入一个URL ......".
默认情况下,在表单身份验证下,浏览器会为用户缓存页面.因此,直接从浏览器地址框下拉列表中选择一个URL,或者键入它,可以从浏览器的缓存中获取页面,并且永远不会返回服务器来检查身份验证/授权.解决方案是在每个页面的Page_Load事件或基页的OnLoad()中阻止客户端缓存:
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Run Code Online (Sandbox Code Playgroud)
您可能还想致电:
Response.Cache.SetNoStore();
Run Code Online (Sandbox Code Playgroud)
Gle*_*tle 11
我之前也在努力解决这个问题.
这是对似乎正在发生的事情的类比......一个新的访问者Joe来到该站点并使用FormsAuthentication通过登录页面登录.ASP.NET为Joe生成一个新标识,并为他提供一个cookie.那个饼干就像是房子的钥匙,只要乔带着那把钥匙回来,他就可以打开锁.每个访问者都会获得一个新密钥和一个新锁.
当FormsAuthentication.SignOut()
被调用时,系统会告诉乔失去的关键.通常,这是有效的,因为乔不再拥有钥匙,他无法进入.
但是,如果Joe回来了,并且确实丢失了钥匙,那么他就会回来!
据我所知,没有办法告诉ASP.NET改变门上的锁!
我可以采用的方法是在Session变量中记住Joe的名字.当他退出时,我放弃了会议,所以我不再有他的名字了.稍后,为了检查他是否被允许,我只是将他的Identity.Name与当前会话的内容进行比较,如果它们不匹配,则他不是有效的访问者.
简而言之,对于一个网站,不要依赖于User.Identity.IsAuthenticated
不检查你的Session变量!
这适合我
public virtual ActionResult LogOff()
{
FormsAuthentication.SignOut();
foreach (var cookie in Request.Cookies.AllKeys)
{
Request.Cookies.Remove(cookie);
}
foreach (var cookie in Response.Cookies.AllKeys)
{
Response.Cookies.Remove(cookie);
}
return RedirectToAction(MVC.Home.Index());
}
Run Code Online (Sandbox Code Playgroud)
经过大量的搜索后,这对我有用.我希望它有所帮助.
public ActionResult LogOff()
{
AuthenticationManager.SignOut();
HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
return RedirectToAction("Index", "Home");
}
<li class="page-scroll">@Html.ActionLink("Log off", "LogOff", "Account")</li>
Run Code Online (Sandbox Code Playgroud)
一般来说要清除用户会话,做
HttpContext.Session.Abandon();
FormsAuthentication.SignOut();
Run Code Online (Sandbox Code Playgroud)
将有效地注销用户。但是,如果在同一个请求中您需要检查Request.isAuthenticated
(例如,可能经常发生在授权过滤器中),那么您会发现
Request.isAuthenticated == true
Run Code Online (Sandbox Code Playgroud)
即使 _after 你做了HttpContext.Session.Abandon()
和FormsAuthentication.SignOut()
。
唯一有效的就是做
AuthenticationManager.SignOut();
HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
Run Code Online (Sandbox Code Playgroud)
这有效地设置Request.isAuthenticated = false
.