ASP.NET Forms身份验证超时
|
这可能是一个非常简单的问题,但是经过几个小时试图了解ASP.NET 4.0的工作原理,我还是不知道. 我正在使用表单验证.我有一个具有登录控件的登录页面. 这是用户登录时需要的: A-用户应该保持记录,直到超时设置不做任何事情.如果他们重新加载页面,超时必须重新启动倒计时. B-如果他们点击“记住我”检查,他们应该保持连接,直到他们注销,无论他们关闭浏览器还是重新启动计算机. 我遇到的问题是登录时,我的电脑上没有看到任何cookie: > Cookie在哪里?是内存cookie吗? 另外我有另一个问题:当他们点击“记住我”检查(案例B),我希望他们记录,直到他们点击注销按钮.这一次我看到一个cookie,但是看起来他们只是为了超时而保持联系…所以Rememeber我有什么区别? 我想完全分离身份验证和会话.我想要通过cookie控制的身份验证,如果接近不是很差. 谢谢你的帮助. 解决方法处理非永久性,滑动过期票表单身份验证使用内存中的Cookie作为故障单,除非您使其持久化(例如,FormsAuthentication.SetAuthCookie(username,true)将使其持久).默认情况下,票证使用滑动到期.每次处理请求时,票据将以新的到期日期向下发送.该日期到期后,Cookie和机票都是无效的,用户将被重定向到登录页面. 表单身份验证没有内置的方法来重定向已经呈现的页面,这些页面比超时时间长.您将需要自己添加.在最简单的层面上,您将需要使用JavaScript启动带有文档加载的计时器. <script type="text/javascript">
var redirectTimeout = <%FormsAuthentication.Timeout.TotalMilliseconds%>
var redirectTimeoutHandle = setTimeout(function() { window.location.href = '<%FormsAuthentication.LoginUrl%>'; },redirectTimeout);
</script>
使用上述方法,如果您的页面没有刷新或更改,或者redirectTimeoutHandle没有被其他方式取消(使用clearTimeout(redirectTimeoutHandle);),它将被重定向到登录页面. FormsAuth机票应该已经过期,所以你不应该做任何事情. 这里的诀窍是您的网站是否执行AJAX工作,或者您将其他客户端事件视为活动用户活动(移动或单击鼠标等).您将必须手动跟踪这些事件,当它们发生时,重置redirectTimeoutHandle.例如,我有一个使用AJAX的站点,所以页面不会经常刷新.由于我使用jQuery,所以每次发出一个AJAX请求时,我都可以重新设置这个超时时间,实际上,如果它们位于单个页面上,而不进行任何更新,那么这个页面将被重定向. 这是一个完整的初始化脚本. $(function() {
var _redirectTimeout = 30*1000; // thirty minute timeout
var _redirectUrl = '/Accounts/Login'; // login URL
var _redirectHandle = null;
function resetRedirect() {
if (_redirectHandle) clearTimeout(_redirectHandle);
_redirectHandle = setTimeout(function() { window.location.href = _redirectUrl; },_redirectTimeout);
}
$.ajaxSetup({complete: function() { resetRedirect(); } }); // reset idle redirect when an AJAX request completes
resetRedirect(); // start idle redirect timer initially.
});
通过简单地发送AJAX请求,客户端超时和票据(以cookie的形式)将被更新,您的用户应该是正常的. 但是,如果用户活动不会导致更新FormsAuth故障单,则用户在下一次请求新页面(通过导航或通过AJAX)时将显示为注销.在这种情况下,当用户活动发生在AJAX调用(例如自定义处理程序,MVC操作等)时,您需要“ping”您的Web应用程序,以使您的FormsAuth票证保持最新.请注意,在ping服务器以保持最新时,您需要小心,因为您不希望洪泛服务器的请求,例如,移动光标或点击事物.除了初始页面加载和AJAX请求之外,还有一个除了初始化脚本之外的添加,将resetRedirect添加到文档上的鼠标点击. $(function() {
$(document).on('click',function() {
$.ajax({url: '/ping.ashx',cache: false,type: 'GET' }); // because of the $.ajaxSetup above,this call should result in the FormsAuth ticket being updated,as well as the client redirect handle.
});
});
处理“永久”门票 您需要将票证作为持久性Cookie发送到客户端,并且具有任意长的超时时间.您应该能够直接离开客户端代码和web.config,而是在登录逻辑中单独处理用户对常规故障单的偏好.在这里,您需要修改机票.以下是登录页面中的逻辑来做这样的事情: // assumes we have already successfully authenticated
if (rememberMe)
{
var ticket = new FormsAuthenticationTicket(2,userName,DateTime.Now,DateTime.Now.AddYears(50),true,string.Empty,FormsAuthentication.FormsCookiePath);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,FormsAuthentication.Encrypt(ticket))
{
Domain = FormsAuthentication.CookieDomain,Expires = DateTime.Now.AddYears(50),HttpOnly = true,Secure = FormsAuthentication.RequireSSL,Path = FormsAuthentication.FormsCookiePath
};
Response.Cookies.Add(cookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(userName,true));
}
else
{
FormsAuthentication.RedirectFromLoginPage(userName,false);
}
奖金:在角色中存储角色 你问你是否可以在门票/ cookie中存储角色,所以你不必再看看.是的,这是可能的,但有一些考虑. >您应该限制您在票中放入的数据量,因为Cookie只能这么大 详细说明#2: 您不应隐含地信任您从用户那里收到的声明.例如,如果用户登录并且是管理员,并检查“记住我”,从而接收持久的长期票证,他们将永远是管理员(或直到该cookie过期或被删除).如果有人从您的数据库中删除该角色,则应用程序仍然认为他们是管理员,如果他们有旧票.因此,您可能会更好地每次获取用户的角色,但是在应用程序实例中缓存角色一段时间,以最大限度地减少数据库的工作. 从技术上讲,这也是机票本身的一个问题.再次,你不应该相信这只是因为他们有一个有效的票证,该帐户仍然有效.您可以使用与角色类似的逻辑:检查由票证引用的用户是否仍然存在,并且通过查询实际的数据库是有效的(它不被锁定,禁用或删除),并且仅缓存数据库结果一段时间时间来提高性能.这是我在我的应用程序中所做的那样,其中机票被视为身份声明(同样,用户名/密码是另一种类型的声明).以下是global.asax.cs(或HTTP模块)中的简化逻辑: protected void Application_AuthenticateRequest(Object sender,EventArgs e)
{
var application = (HttpApplication)sender;
var context = application.Context;
EnsureContextUser(context);
}
private void EnsureContextUser(HttpContext context)
{
var unauthorizedUser = new GenericPrincipal(new GenericIdentity(string.Empty,string.Empty),new string[0]);
var user = context.User;
if (user != null && user.Identity.IsAuthenticated && user.Identity is FormsIdentity)
{
var ticket = ((FormsIdentity)user.Identity).Ticket;
context.User = IsUserStillActive(context,ticket.Name) ? new GenericPrincipal(user.Identity,GetRolesForUser(context,ticket.Name)) : unauthorizedUser;
return;
}
context.User = unauthorizedUser;
}
private bool IsUserStillActive(HttpContext context,string username)
{
var cacheKey = "IsActiveFor" + username;
var isActive = context.Cache[cacheKey] as bool?
if (!isActive.HasValue)
{
// TODO: look up account status from database
// isActive = ???
context.Cache[cacheKey] = isActive;
}
return isActive.GetValueOrDefault();
}
private string[] GetRolesForUser(HttpContext context,string username)
{
var cacheKey = "RolesFor" + username;
var roles = context.Cache[cacheKey] as string[];
if (roles == null)
{
// TODO: lookup roles from database
// roles = ???
context.Cache[cacheKey] = roles;
}
return roles;
}
当然,你可能会决定你不关心任何一个,只是想相信票,并把角色存放在票上.首先,我们从上面更新您的登录逻辑: // assumes we have already successfully authenticated
if (rememberMe)
{
var ticket = new FormsAuthenticationTicket(2,GetUserRolesString(),true));
}
else
{
var ticket = new FormsAuthenticationTicket(2,DateTime.Now.AddMinutes(FormsAuthentication.Timeout),false,FormsAuthentication.FormsCookieName);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,FormsAuthentication.Encrypt(ticket))
{
Domain = FormsAuthentication.CookieDomain,Path = FormsAuthentication.FormsCookiePath
};
Response.Cookies.Add(cookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(userName,false));
}
添加方法: private string GetUserRolesString(string userName)
{
// TODO: get roles from db and concatenate into string
}
更新您的global.asax.cs以获取角色,并更新HttpContext.User: protected void Application_AuthenticateRequest(Object sender,EventArgs e)
{
var application = (HttpApplication)sender;
var context = application.Context;
if (context.User != null && context.User.Identity.IsAuthenticated && context.User.Identity is FormsIdentity)
{
var roles = ((FormsIdentity)context.User.Identity).Ticket.Data.Split(",");
context.User = new GenericPrincipal(context.User.Identity,roles);
}
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – Visual Studio 2012不发布项目
- asp.net-mvc – 在MVC中,何时使用%=%和%%?
- asp.net:runat =“server”和服务器控件之间的区别
- asp.net – 如何单元测试使用HostingEnvironment.MapPath的
- asp.net – Mysql中int(10)的最大大小是多少?
- asp.net-mvc – ASP.NET MVC 2预览2:区域重复控制器问题
- asp.net-mvc – asp.net mvc 3预选Html.DropDownListFor不能
- asp.net – Bind()还是Eval()自动使用HtmlEncode来防范XSS?
- asp.net-mvc – HttpResponse.RemoveOutputCacheItem不工作
- asp.net-mvc-3 – 为什么这个代码不删除布局?
- asp.net – NavigateUrl =“#”变成href =“SubF
- 从ASP.NET应用程序使用Active Directory时,Direc
- 单元测试传统ASP.NET Webforms应用程序
- asp.net-mvc – 如何在asp.net中使用Captcha mvc
- MVC 5远程验证
- asp.net – 如何在EF Core中向Identity用户添加外
- asp.net-mvc – 如何在asp.net mvc中的静态类中获
- 用于访问Gravatar图像的ASP.NET MVC帮助器
- asp.net – 在Gridview中有条件地隐藏CommandFie
- asp.net-mvc – 自定义DateTime模型绑定在Asp.ne
