Pergunta

Eu tenho um projeto em execução MVC4 e o uso de Simples Associação para autenticação.Eu só deseja permitir que um usuário se logar em um navegador.Para tornar isso transparente para o usuário, eu preciso de uma maneira de ter qualquer outro navegador autenticada log out sempre que um usuário fizer logon.Isso significa que, se dois usuários estão tentando usar o mesmo login, eles simplesmente continuamente chutar uns aos outros fazendo com que muito improdutivo.

Agora, eu tenho que configurar para apenas permitir que um usuário faça o login uma vez, mas se o usuário fechar o navegador e ir para outro computador, que deve ser bloqueado por 30 minutos eu posso ver isso da criação de um número de chamadas de suporte desnecessárias.

Eu diria que eu preciso para controlar algum tipo de identificador em um banco de dados e verifique se ele corresponde com cada pedido, caso contrário eles estão desconectados.Talvez, a adição de algum tipo de biscoito.

Se alguém tiver uma solução elegante para isso, eu agradeceria!

Isso é o que eu estou usando atualmente para bloqueio de usuários em apenas um login:

Login:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    string sKey = model.UserName;
    string sUser = Convert.ToString(System.Web.HttpContext.Current.Cache[sKey]);

    if (sUser == null || sUser == String.Empty)
    {
        TimeSpan SessTimeOut = new TimeSpan(0, 0, System.Web.HttpContext.Current.Session.Timeout, 0, 0);
        System.Web.HttpContext.Current.Cache.Insert(sKey, sKey, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);

        Session["user"] = model.UserName;

        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        {
            return RedirectToLocal(returnUrl);
        }

        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "The user name or password provided is incorrect.");
    }
    else
    {
        ModelState.AddModelError("", "You are already logged in.");
   }

    return View(model);
}

Globais.asax

protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
    if (HttpContext.Current.Session != null)
    {
        if (Session["user"] != (null)) // e.g. this is after an initial logon
        {
            string sKey = (string)Session["user"];
            // replace the last hit with current time
            // Accessing the Cache Item extends the Sliding Expiration automatically
            string sUser = (string)HttpContext.Current.Cache[sKey];
        }
    }
}

Logout:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    UserProfile user = db.UserProfiles.SingleOrDefault(s => s.UserName == User.Identity.Name);
    string sKey = user.UserName;
    System.Web.HttpContext.Current.Cache.Remove(sKey);
    WebSecurity.Logout();
    return RedirectToAction("Start", "Home");
}

Eu tinha usado o termo da sessão e o removeu.Eu não estou tentando excluir o usuário da sessão, mas fazer a sua autorização inválida usando a segurança na web.

Foi útil?

Solução

Não há nada de especialmente criado para isso.Você tem que desenvolver algumas metodologia em seu próprio país.Você tinha precisa basicamente de duas partes:

  1. Alguma forma de acompanhamento de um utilizador com sessão iniciada através dos pedidos.Isso pode ser tão simples como uma tabela com uma coluna nome de usuário que você pode usar para determinar se determinado nome de usuário foi conectado.Você precisa manter isso em sincronia com seus logins/logouts, claro, e você também seria necessário para armazenar o id de sessão para o utilizador.Você vai precisar de que para a próxima peça:

  2. Algum mecanismo de remover a sessão a partir de qualquer loja ela existe.Isso seria mais fácil se você estiver usando o SQL sessões, como você poderia simplesmente excluir a linha da tabela tabela de sessão com o id de correspondente.Não há nenhuma maneira de fazer isso diretamente com ASP.NET, então você teria que consultar diretamente o banco de dados utilizado um procedimento armazenado, etc.

Assim, a idéia geral seria a de que quando um usuário efetua logon, você grava seu nome de usuário e id de sessão em uma tabela ou algum outro persistentes loja.Quando alguém tenta entrar, você iria verificar com esta loja para o nome de usuário que está sendo tentada, e se ele existir, vá eliminar a sessão que corresponde a esta.A próxima vez que o utilizador com sessão tenta aceder a uma página, o seu cookie de sessão não irá corresponder uma sessão válida e eles vão ser tratados como se estive logged out.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top