none
Validação de Login na Aplicação

    Question

  • Prezados,

    Como posso validar se um usuário está logado (com base em um tabela de usuários (tb_Usuarios, por exemplo) ao chamar uma URL de uma aplicação MVC.

    Exemplo: Ao chamar a url http://minhaurl/Camapanhas , a aplicação deve verificar se o usuário passou pelo processo de autenticação, caso não deve ser redirecionado a uma determinada URL (de Login por exemplo). Esse controller de autenticação está criado, consultando o banco de dados e validando usuário e senha. Mas não sei como validar se o login foi efetuado.

    Pesquisando encontrei a utilização do SessionState e Authorize. Qual a diferença entre os dois? Acredito que o authorize seja o indicado, mas como validar meus usuários no BD?

    Criei até uma classe onde persisto alguns dados, como login, ID da conexão (gerado pela função newid() do sql server) e outros ID's que utilizarei no decorrer da aplicação.

    ps: não são usuários do SQL Server, mas registros em uma tabela personalizda.

    Abs.

    Tuesday, April 12, 2011 6:34 PM

All replies

  • Oi Anselmo.

    Eu tinha um cenário parecido com o seu a um tempo atrás, e resolvi o problema usando Forms Authentication.

    O Forms Authentication faz todo esse trabalho de controlar se o usuário está ou não logado, tudo via session, sem que você tenha que ficar se preocupando em fazer essa validação a cada Action ou Controller da sua aplicação.

    Aqui vai alguns links falando sobre o Forms Authentication, tanto no MVC quando no WebForms, o uso dele em um ou outro não muda muito.

    http://weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework-using-forms-authentication.aspx

    http://www.asp.net/mvc/tutorials/authenticating-users-with-forms-authentication-cs

    http://mikehadlow.blogspot.com/2008/03/forms-authentication-with-mvc-framework.html

    Espero ter ajudado.


    Aprender é a única coisa de que a mente nunca se cansa, nunca tem medo, e nunca se arrepende.
    Tuesday, April 12, 2011 8:42 PM
  • Uma forma basica é voce usar o atributo [Authorize] em cima das suas actions ou controllers que deseja barrar o acesso a usuario nao logados.

    E no seu form de login, se a autenticação for feita com sucesso usar seguinte método:

    FormsAuthentication.SetAuthCookie(usuario.Login, true);

    Dessa maneira o usuario vai ficar logado, e o Authorize nao vai barrar.


    Contato:albertim_brasil@hotmail.com - Se ajudei, marca como útil.
    Twitter: Me siga!!
    Blog:http://albertomonteiro.net/

    Tuesday, April 12, 2011 9:00 PM
  • Olá Leonardo,

    Eu cheguei a ver em alguns sites esse funcionamento. Mas não gostaria de utilizar algo criado por padrão. Como o projeto da minha aplicação foi criadado comm "Empty" não foi gerado esse recurso e gostaria ainda de Entender como é realizado essa autenticação.

    Acho que o primeiro link dá uma luz... vou ver aqui...

    Valeu pela dica.

    abs.

    Tuesday, April 12, 2011 9:04 PM
  • Alberto, 

    Funcionou legal, porém, ao fechar o browser e abri-lo novamente, o usuário continua logado. Como resolver isso, ou seja, ao fechar o browser a sessão é encerrada?

    Obrigado e Abs.

    Wednesday, April 13, 2011 12:02 AM
  • No global.asax - evento Session_OnEnd - você pode dar um FormsAuthentication.SignOut()
    Wednesday, April 13, 2011 2:29 PM
    Moderator
  • No meu arquivo global.asax não possui tal evento.

    Seria dessa forma:

    public void Session_OnEnd()
    {
          FormsAuthentication.SignOut();
    }
    
    abs;
    Wednesday, April 13, 2011 7:19 PM
  • da uma olhada nesse artigo

     

    http://andrecypreste.wordpress.com/2011/01/25/configurando-roleprovider-com-roles-fixas/


    E-mail: dnbdub@msn.com Twitter: MaxEvol
    Wednesday, April 13, 2011 11:31 PM
  • Anselmo pego o webcast do mvc sobre membership no mvc é muito bom e me serviu


    Junior
    Friday, April 15, 2011 1:16 PM
  • Junior_Luiz

    Procurei por este WebCast e nao encontrei.
    Voce tem ele ai? Tem como me passar?

    Obrigado!

    Wednesday, May 25, 2011 5:29 PM
  • Marcelo basicamente vc faz assim, criar uma classe tipo meumembership que herda de membershipprovider nela vc terá que implementar apenas o ValidateUser apontando para seu banco e tabelas, feito isso no webconfig vc muda apontando para a sua classe meumembershipprovider, assim vc fez a validação do usuario, para fazer o provider faz a mesma coisa cria uma classe meuprovider herdando de RolerProvider nela vc vai implementar em GetRolesForUse e em GetUserInRole suas regras vai no webconfig e altera tb para ele acessar sua classe e ponto vc já pode user o [authorize], comigo funciona perfeito, qualquer duvida é so postar

     


    Junior
    Wednesday, May 25, 2011 6:07 PM
  • Junior,

    Fiz um leitura do link que voce me  passou e peguei tambem o resumo que voce passou acima. Fiz a metade do que voce descreveu:

    Criei uma classe e esta herdou de MembershipProvider, em seguida apenas  para teste reescre o metodo ValidateUser, ficou assim:

    public class MyMemberShip : MembershipProvider
    {
    
    public override bool ValidateUser(string username, string password)
      {
        if (username == "admin" || password == "admin")
          return true;
        else
          return false;
      }
    

     

    Feito isso alterei meu WebConfig e o mesmo ficou assim:

      <authentication mode="Forms">
       <forms loginUrl="~/Usuario/LogIn" timeout="2880" />
      </authentication>
    
      <membership defaultProvider="CustomMembershipProvider">
       <providers>
        <clear/>
        <add name="CustomMembershipProvider"
           type="MyMemberShip"
           connectionStringName="ApplicationServices"
           enablePasswordRetrieval="false"
           enablePasswordReset="true"
           requiresQuestionAndAnswer="false"
           requiresUniqueEmail="false"
           maxInvalidPasswordAttempts="5"
           minRequiredPasswordLength="6"
           minRequiredNonalphanumericCharacters="0"
           passwordAttemptWindow="10"
           applicationName="/" />
       </providers>
      </membership>
    

     

    Depois no meu ClienteController na Action Create eu fiz:

        // Create - GET
        [Authorize]
        public ActionResult Create()
        {
          return View();
        }
    

     

    Entao se tento acessar a action Create sou redireciona para a pagina de logon. No meu UsuarioController na Action Login ficou assim:

        [HttpPost]
        public ActionResult LogIn(Usuario UsuarioAutentica, string returnUrl)
        {
          if (ModelState.IsValid)
          {
            MyMemberShip _myms = new MyMemberShip();
            if (_myms.ValidateUser(UsuarioAutentica.Logon, UsuarioAutentica.Senha))
            {
              FormsAuthentication.SetAuthCookie(UsuarioAutentica.Logon, true);
              if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
              {
                return Redirect(returnUrl);
              }
              else
              {
                return RedirectToAction("Index", "Home");
              }
            }
            else
            {
              ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
          }
    
          // If we got this far, something failed, redisplay form
          return View(UsuarioAutentica);
        }
    

     

    Finalmente  digitando logon e senha e sendo validado sou redirecionado para onde eu tentei anteriormente. Depois disso tudo funciona corretamente.

    Por agora  nao vou implementar as RoleProvider, vou dar uma estudada nesta parte.

    Minha duvida é se ficou faltando algo, tipo mais alguma coisa que precise ser feito para "fortalecer" esta rotina de autenticacao.

    Obrigado pela atençao.

    abs!

    Thursday, May 26, 2011 10:38 PM
  • Marcelo no meu caso tenho 3 tabelas uma de usuario,grupo,usuariogrupo em um relacionamento de N->N, no meu controller acesso a tabela de usuario, assim fica tudo dinamico
    public override bool ValidateUser(string username, string password)
        {
          using (sysvtrEntities db = new sysvtrEntities())
          {
            var result = from u in db.Usuario where (u.Login == username && u.Senha == password) select u;
    
            if (result.Count() != 0)
            {
              var dbuser = result.FirstOrDefault();
    
              var result1 = from e in db.Empresa where (dbuser.Cdempr == e.cdempr) select e;
              var codemp = dbuser.Cdempr;
              var empresa = result1.FirstOrDefault();
              
              return true;
            }
            else
            {
              return false;
            }
    
          }
        }
    

     

    Criei tb session pois no meu caso preciso na aplicação e no homecontroller fiz assim

    public ActionResult Index()
        {
          Usuario user = db.Usuario.FirstOrDefault(u => u.Login == HttpContext.User.Identity.Name);
          if (user != null)
          {
            var result = from e in db.Empresa where (user.Cdempr == e.cdempr) select e;
    
            var empresa = result.FirstOrDefault();
            var codemp = user.Tb_Base_Empresa.cdempr;
            var nomeusu = user.Nome; 
            Session["Empresa"] = empresa.nmabre;
            Session["CodEmpresa"] = codemp;
            Session["NomeUsuario"] = nomeusu; 
          }
          return View();
        }
    
    no _logonpartial alterei e assim que o usuário é autenticado mostro no meu caso o nome do usuario e o codigo e nome da empresa dele
    
    ficou assim
    
    <pre lang="x-c#">@if(Request.IsAuthenticated) {
       <text><b>Usuário Conectado:</b>&nbsp;@Session["NomeUsuario"]
       <br />
       <b>Empresa : </b> @Session["CodEmpresa"] - @Session["Empresa"]
      [ @Html.ActionLink("Log Off", "LogOff", "Account") ]</text>
    }
    else {
      @:[ @Html.ActionLink("Log On", "LogOn", "Account") ]
    }
    
    Se vc precisar de mando o provider mais a idéia é a mesma sim e no _layout está assim no menu
    
    <pre lang="x-c#">@if (Request.IsAuthenticated && HttpContext.Current.User.IsInRole("RH"))
              {
                <li>@Html.ActionLink("Recursos Humanos", "Index", "Funcionario")</li>
              }
    else
              {
                <li>@Html.ActionLink("Início", "Index", "Home")</li>
                
                <li>@Html.ActionLink("Sobre", "About", "Home")</li>
              }
    


    Junior
    Friday, May 27, 2011 11:35 AM
  • Junior,

    Consegui entender tudo que voce fez e desta maneira fica tudo dinamico mesmo. Mas a duvida que ainda tenho é se este modelo de autenticacao e depois autorizacao seria o mais seguro. Vou tentar exemplificar para ficar mais claro. Vamos imaginar uma aplicacao que  vai ser acessada por milhares de usuarios ao mesmo tempo, dou como exemplo o facebook. Se eu fosse fazer algo do porte do facebook poderia usar este modelo de autenticacao e depois autorizacao sem medo de ser feliz?

    Ou seja falando em ASP.NET MVC3 este modelo de autenticacao é o mais seguro?

    Obrigado pela atenção.

    Abs.

    Friday, May 27, 2011 1:53 PM
  • Marcelo estamos herdando nossa classe de uma classe implementada por padrão pelo asp.net, mais claro se for o caso sempre é bom implementar algo, por exemplo tenho um sistema em webforms que eu estava tendo problemas com session e então implementei cookies mais atualizando uma tabela onde qdo o usuario se loga gravo nessa tabela e sempre checo o cookie com essa tabela, o usuário saiu da aplicação deleto alinha do banco assim essa tabela é sempre pequena, implementei tb criptografia no cookie assim fica mais seguro, mais entenda o seguinte segurança nunca é demais, vc que é o dono do sistema deverá ver a melhor maneira de gerenciar isso.

    No meu caso tb estou estudando MVC e estou partindo de uma extranet em webforms e refazendo em MVC os usuários no meu caso não são muitos e todos eu tenho que cadastrar previamente, portanto não preciso de danta segurança assim, mais se esse for o seu caso, pesquise sobre o assunto e veja a melhor forma de implementar o que vc quer.


    Junior
    Friday, May 27, 2011 2:11 PM
  • Blz Junior,

    Vou dar uma pesquisada na net sobre o assunto pois meu aplicativo tera muitos acessos simultaneos. Nao sera nada tao grande como o exemplo que dei mas o quesito segurança tem de estar bem alinhado pois as informacoes sao de terceiros ai ja viu né.

    Que tipo de topicos voce acha que eu posso buscar na internet para me interar mais sobre o quesito seguranca?

     

    Valew pela força!

    Friday, May 27, 2011 2:22 PM
  • Procura sobre a classe membershipprovider já que estamos herdando dela, e veja a parte de cookies e session pois só existem essas duas implementações para passar informações entre páginas.

    Cada implementação tem suas vantagens e desvantagens, como te falei acima tenho um sistema que é muito acessado e estava com problemas nas session pois quem gerenciar é o iis ai resolvi como te falei implementando cookies e gravando os dados no banco, mais se o usuário no navegador desabilitar os cookies o site não funciona apesar de que se isso acontecer tenho uma página que mostro como habilitar, só mais uma coisa se vc optar por usar cookies criptografe o arquivo pois ele fica no micro do usuário e assim vc garante que o usuário nao altere esse arquivo e assim seu sistema não vai ter um furo na segurança. Como te falei existens as vantagens e desvantagens de cada abordagem.


    Junior
    Friday, May 27, 2011 2:50 PM