Как я могу принудительно выйти из системы всех пользователей для веб-сайта?
Я использую MySQL, Connector/.NET, все его провайдеры с FormsAuthentication.
Мне нужно, чтобы все пользователи выходили из системы в какой-то момент. Метод FormsAuthentication.SignOut()
не работает как я хочу.
Как я могу выйти из системы всех пользователей сайта?
2 ответа
Как предполагает Джо, вы могли бы написать HttpModule для аннулирования любых файлов cookie, присутствующих до заданного DateTime. Если вы поместите это в файл конфигурации, вы можете добавить / удалить его при необходимости. Например,
Web.config:
<appSettings>
<add key="forcedLogout" value="30-Mar-2011 5:00 pm" />
</appSettings>
<httpModules>
<add name="LogoutModule" type="MyAssembly.Security.LogoutModule, MyAssembly"/>
</httpModules>
HttpModule в MyAssembly.dll:
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();
}
}
}
Основа с @ Бретом большого ответа. Я обработал несколько сценариев, которые позволяют принудительному выходу из системы происходить после того, как пользователь вошел в систему (в или после) даты, указанной в файле конфигурации (нет необходимости рассчитывать даты истечения срока действия в будущем). Я считаю, что использование его ответа приведет к тому, что пользователь будет постоянно выходить из системы, если срок действия cookie-файлов наступает до даты принудительного выхода. Кроме того, я не уверен, как он смог получить срок действия cookie, используя файл cookie в запросе. В своих попытках я всегда получал значение по умолчанию DateTime , как объясняется здесь: Срок действия cookie ASP.NET всегда 1/1/0001 12:00 AM.
Итак, идея здесь в том, что вам нужно будет добавить DateTime для создания файла cookie к принципалу (ПРИМЕЧАНИЕ: тип должен иметь значение DateTime, допускающее значение NULL. Это позволит обрабатывать, если это изменение будет внесено на уже используемый сайт - поскольку принципал до этого не содержать это дополнительное поле).
Вы настраиваете web.config, как он:
<configuration>
<appSettings>
<add key="forcedLogout" value="03-Feb-2021 10:46 pm" />
</appSettings>
</configuration>
для добавления модуля в web.config необходимо определить, используете ли вы интегрированный режим пула приложений или классический режим пула приложений :
<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;
}
}