2016-10-31 3 views
2

У меня есть веб-системы, разработанной с помощью ASP.NET MVC 4.пользователь Капля проверку подлинности в ASP.NET MVC

У нас есть управление пользователями, что позволяет пользователям редактировать/удалять пользователей. В функции удаления, в настоящее время я делаю только delete в базе данных.

Так вот мой login контроллера/метод:

[HttpPost] 
public ActionResult Login(LoginViewModel loginViewModel) 
{ 
    if (_loginService == null) 
     _loginService = new LoginService(); 

    var result = _loginService.Login(loginViewModel.User, loginViewModel.Password); 
    if (!result.Error) 
    { 
     var userData = JsonConvert.SerializeObject(result.User); 
     FormsAuthentication.SetAuthCookie(result.User.Id, false); 
     var ticket = new FormsAuthenticationTicket(1, result.Id, DateTime.Now, DateTime.Now.AddMinutes(9999), true, userData, FormsAuthentication.FormsCookiePath); 
     var encryptedCookie = FormsAuthentication.Encrypt(ticket); 
     var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie) { Expires = DateTime.Now.AddHours(14) }; 

     Response.Cookies.Add(cookie); 
    } 
    return new JsonResult 
    { 
     Data = result 
    }; 
} 

И я лечу, что возвращение на стороне клиента с некоторым JavaScript. К настоящему времени это работает нормально.

Для каждого Контролера, который должен быть аутентифицирован, у меня есть атрибут [Authorize].

Допустим, что я только что вошёл в систему с пользователем ABC. Пока ABC cookie жив, он может хорошо перемещаться .. проблема в том, что некоторые пользователи (скажем ZXC) удаляют пользователя ABC, он все равно будет хорошо перемещаться до истечения срока действия файла cookie.

Есть ли способ отказаться ABC сеанс на IIS в момент ZXC удаляет его из базы данных? Я не знаю .. заставляют печенье истекать. Я просто не хочу реализовывать консультацию для каждого действия, выполняемого в навигации, чтобы проверить, остается ли пользователь «живым» в базе данных.

Любые идеи, предложения?

ответ

2

Во-первых, нет. Невозможно получить доступ к файлам cookie в другом сеансе, поскольку они существуют только для времени жизни запроса/ответа. Тем не менее, вы можете сохранить статические List всех текущих пользователей, прошедших проверку подлинности, и сделать их недействительными.

Это немного проблематично, потому что в случае повторного использования пула приложений все пользователи будут «выходить из системы». Если это не является проблемой для вас (то есть приложение бассейн перерабатывает в 2 часа ночи, и для бизнес-системы, которая не работает в 2 часа ночи), то вы можете попробовать это ...

кодекс предусматривает неопробованные

источник: https://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationmodule.authenticate

EDIT:
я не удалял куки из запроса и истекающий его в ответ.

В глобальном масштабе.asax

private static List<string> _authenticatedUsers = new List<string>(); 

public static AuthenticateUser (MyApplicationUser user) 
{ 
    if(!_authenticatedUsers.ContainsKey(user.Username)) 
    { 
     _authenticatedUsers.Add(user.Username); 
    } 
} 

public static DeauthenticateUser (MyApplicationUser user) 
{ 
    if(_authenticatedUsers.ContainsKey(user.Username)) 
    { 
     _authenticatedUsers.Remove(user.Username); 
    } 
} 

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args) 
{ 
    if (FormsAuthentication.CookiesSupported) 
    { 
    if (Request.Cookies[FormsAuthentication.FormsCookieName] != null) 
    { 
     try 
     { 
     FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(
      Request.Cookies[FormsAuthentication.FormsCookieName].Value); 

     MyApplicationUser user = JsonConvert.DeserializeObject(ticket.UserData); 

     if(user == null || !_authenticatedUsers.Any(u => u == user.Username)) 
     { 
      // this invalidates the user 
      args.User = null; 
      Request.Cookies.Remove(FormsAuthentication.FormsCookieName); 
      HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName); 
      DateTime now = DateTime.Now; 

      myCookie.Value = "a"; 
      myCookie.Expires = now.AddHours(-1); 

      Response.Cookies.Add(myCookie); 
      Response.Redirect(FormsAuthentication.LoginUrl); 
      Resonpse.End(); 
     } 
     } 
     catch (Exception e) 
     { 
     // Decrypt method failed. 
     // this invalidates the user 
     args.User = null; 
     Request.Cookies.Remove(FormsAuthentication.FormsCookieName); 
     HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName); 
     DateTime now = DateTime.Now; 

     myCookie.Value = "a"; 
     myCookie.Expires = now.AddHours(-1); 

     Response.Cookies.Add(myCookie); 
     Response.Redirect(FormsAuthentication.LoginUrl); 
     Resonpse.End(); 
     } 
    } 
    } 
    else 
    { 
    throw new HttpException("Cookieless Forms Authentication is not " + 
          "supported for this application."); 
    } 
} 

В вашей авторизации действия

public ActionResult Login(LoginViewModel loginViewModel) 
{ 
    ... 

    if (!result.Error) 
    { 
     ... 
     MvcApplication.AuthenticateUser(result.User); 
     ... 
    } 
    ... 
} 

В вашем выходе из системы действия

public ActionResult Logout(...) 
{ 
    ... 
    MvcApplication.DeauthenticateUser(user); 
    ... 
} 

В вашем методе удаления

... 
MvcApplication.DeauthenticateUser(user); 
... 
+0

спасибо за ваше время. Я думаю, что это подход ... но мне все еще интересно, есть ли другие варианты ... Я знаю, что в java мы можем использовать 'JMX-интерфейс', чтобы сделать это ... в C# должно быть что-то похожее. –

+0

Вы можете создавать свои собственные обработчики сеансов и перечислять их, но это в значительной степени то, что делает 'List '. Куки-файлы не существуют на стороне сервера, поэтому невозможно изменить один из них, который не является частью текущего запроса. –

+0

Нет ничего другого. Я имею в виду, что не существует способа для 'formsauthentication.signout()' передачи идентификатора 'например'? to 'signout()' удаленный пользователь? –

Смежные вопросы