我正在使用MySQL Connector / .NET,其所有提供程序都使用FormsAuthentication。
我需要所有用户在某个时刻退出。方法FormsAuthentication.SignOut()
不能像我想的那样工作。
如何注销所有网站用户?
答案 0 :(得分:15)
正如Joe建议的那样,您可以编写一个HttpModule来使给定DateTime之前存在的任何cookie无效。如果将其放在配置文件中,则可以在必要时添加/删除它。例如,
<强>的Web.config:强>
<appSettings>
<add key="forcedLogout" value="30-Mar-2011 5:00 pm" />
</appSettings>
<httpModules>
<add name="LogoutModule" type="MyAssembly.Security.LogoutModule, MyAssembly"/>
</httpModules>
MyAssembly.dll中的HttpModule:
public class LogoutModule: IHttpModule
{
#region IHttpModule Members
void IHttpModule.Dispose() { }
void IHttpModule.Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
}
#endregion
/// <summary>
/// Handle the authentication request and force logouts according to web.config
/// </summary>
/// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
private void context_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication a = (HttpApplication)sender;
HttpContext context = a.Context;
// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = context.Request.Cookies[cookieName];
DateTime? logoutTime = ConfigurationManager.AppSettings["forcedLogout"] as DateTime?;
if (authCookie != null && logoutTime != null && authCookie.Expires < logoutTime.Value)
{
// Delete the auth cookie and let them start over.
authCookie.Expires = DateTime.Now.AddDays(-1);
context.Response.Cookies.Add(authCookie);
context.Response.Redirect(FormsAuthentication.LoginUrl);
context.Response.End();
}
}
}
答案 1 :(得分:0)
基于 @Bret's 很好的答案。我处理了一些场景,这些场景允许在用户登录(或之后)配置文件中指定的日期(无需计算未来的到期日期)后发生强制注销。我相信如果 cookie 过期时间在强制注销日期之前,使用他的回答将导致用户不断被注销。此外,我不确定他是如何使用请求中的 cookie 来检索 cookie 过期的。在我的尝试中,我总是收到 DateTime 默认值,如下所述:ASP.NET cookie expiration time is always 1/1/0001 12:00 AM
所以这里的想法是您需要将 cookie 创建 DateTime 添加到主体(注意:类型应该是可为空的 DateTime。如果已经对站点进行了此更改,则这将允许处理正在使用 - 作为在此之前的主体不包含此额外字段)。
您像他一样设置了 web.config:
<configuration>
<appSettings>
<add key="forcedLogout" value="03-Feb-2021 10:46 pm" />
</appSettings>
</configuration>
要将模块添加到 web.config,您需要确定是否使用 application pool integrated mode vs application pool classic mode:
<system.webServer><!--for integrated mode-->
<modules>
<add name="ForceLogoutModule" type="AssemblyName.NameSpace.ForceLogoutModule", AssemblyName />
</modules>
</system.webServer>
<system.web><!--for classic mode-->
<httpModules>
<add name="ForceLogoutModule" type="AssemblyName.NameSpace.ForceLogoutModule", AssemblyName />
</httpModules>
</system.web>
或者您可以像这样以编程方式添加模块(在 global.asax 中):
public static IHttpModule Module = new ForceLogoutModule();
public override void Init()
{
base.Init();
Module.Init(this);
}
然后你的 ForceLogout 模块(可以在同一个项目中):
public class ForceLogoutModule : IHttpModule
{
#region IHttpModule Members
void IHttpModule.Dispose() { }
void IHttpModule.Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
}
#endregion
/// <summary>
/// Handle the authentication request and force logouts according to web.config
/// </summary>
/// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
private void context_AuthenticateRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender as HttpApplication).Context;
JavaScriptSerializer serializer = new JavaScriptSerializer();
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = context.Request.Cookies[cookieName];
if (authCookie == null)
return;
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
CustomPrincipalSerializeModel principal = serializer.Deserialize<CustomPrincipalSerializeModel>(ticket.UserData);
DateTime logoutTime;
DateTime cookieCreation = ticket.IssueDate;
if (!this.TryParseNullableToDate(ConfigurationManager.AppSettings["forcedLogout"], out logoutTime))
return;
if (!principal.Expiration.HasValue
|| (principal.Expiration.Value.ToLocalTime() > logoutTime && cookieCreation < logoutTime
&& DateTime.Now >= logoutTime.Date))
{
authCookie.Expires = DateTime.Now.AddDays(-1);
context.Response.Cookies.Add(authCookie);
context.Response.Redirect(FormsAuthentication.LoginUrl);
context.Response.End();
}
}
private bool TryParseNullableToDate(string value, out DateTime dateTime)
{
DateTime temp;
if (string.IsNullOrWhiteSpace(value) || !DateTime.TryParse(value, out temp))
{
dateTime = DateTime.MinValue;
return false;
}
dateTime = temp;
return true;
}
}