Fórum Autenticação #8446

07/08/2009

0

Quero que uma aplicação possua login de usuário, sem usar os componentes prontos.

O que eu fiz, e não está funcionando corretamente:

Tenho as pastas: pastaA, pastaB e pastaC.

Uma página de login: default.aspx.

No web.config, coloquei a instrução:
<authentication mode="Forms">
      <forms name="Autenticação" loginUrl="Default.aspx" path="/" timeout="30" slidingExpiration="true" cookieless="AutoDetect" protection="All" />
    </authentication>

Quando o usuário digita o login e a senha, faço as verificações de praxe, e dependendo do tipo de usuário, quero que ele seja redirecionado para uma determinada pasta dentre as 3 citadas acima (A, B ou C).

Se o usuário puder acessar a pastaA, não pode acessar a pastaB e pastaC, a mesma lógica vale para as demais.

Para fazer esse controle, utilizei a ferramenta ASP.Net Configuration (menu Project ASP.Net Configuration do Visual Studio) e criei 3 usuários: usuarioA, usuarioB e usuarioC. Em seguida, criei 3 funções (Roles): usuarioA, usuarioB e usuarioC, atribuindo à cada função o usuário correspondente.

O próximo passo foi criar um web.config em cada pasta, com o seguinte código:
<configuration>
  <system.web>
    <authorization>
      <deny users="?" roles="usuarioB,usuarioC" />
      <allow roles="usuarioA"/>
    </authorization>
  </system.web>
</configuration>

Esse web.config foi copiado para demais pastas e ajustado conforme cada uma para terem as configurações corretas.

Pois bem, a priori, o sistema de segurança funciona, pois o usuário autenticado não consegue acessar as pastas que não sejam a autorizada para o seu acesso. No entanto, o código só funciona adequadamente quando o usuário tenta acessar a página previamente, ou seja, antes de fazer o login, usando o código FormsAuthentication.RedirectFromLoginPage("usuarioA", false).

Para contornar esse problema, ao invés do código acima, utilizei o seguinte:
FormsAuthentication.SetAuthCookie("usuarioA", false);
                    Server.Transfer("~/usuarioA/usuarioA.aspx");

Até aí tudo bem, a página correta é aberta, mas tem um problema: o browser não é redirecionado propriamente dito para a página, e sim ela é aberta no mesmo local, sendo que são passados alguns parâmetros pela string de URL automaticamente pelo ASP.Net. O segundo efeito colateral que pude observar é que, mesmo que o usuário ao tentar acessar uma página na qual não tem permissão, ser redirecionado novamente à página de login, efetuar o login corretamente para o novo usuário, o nome de usuário não muda para os controles internos do ASP.Net, pois ao tentar saber qual o usuário que está logado ele informa o primeiro usuário que fez logon e não o último, apesar do controle de acesso às pastas funcionar perfeitamente.

Enfim, esse relato foi apenas para citar o que já fiz. Resumidamente, o que eu preciso é:
Ter 3 usuários distintos que devem acessar 3 pastas distintas dentro da aplicação. Cada usuário não pode ver as outras duas pastas da qual ele não tem autorização.
Quero, a partir da página principal, no momento que usuário fizer logon, seja redirecionado para a página correta, sem necessidade de ter que tentar acessar a página antes.
Não há necessidade de usar o que eu fiz e comentei acima. O importante é funcionar!

Obrigado.
Celso Paganelli

Celso Paganelli

Responder

Posts

10/08/2009

Fabio Mans


Olá pelo que percebi tudo está funcionando corretamente, porém você precisa fazer alguns ajustes.

Vamos descrever abaixo.

1 - O segundo efeito colateral que pude observar é que, mesmo que o usuário ao tentar acessar uma página na qual não tem permissão, ser redirecionado novamente � página de login, efetuar o login corretamente para o novo usuário.

No caso acima eu faço o seguinte eu crio uma página chamada AcessoNegado.aspx e coloco o código abaixo na página Login.aspx

protected void Page_Load(object sender, EventArgs e)
    {
        if (User.Identity.IsAuthenticated && Request.QueryString["ReturnUrl"] != null)
            Response.Redirect("AcessoNegado.aspx");      
    }

Se ele estiver logado e na query string conter ReturnUrl significa que ele está tentando acessar uma área que não tem acesso.



2 - o nome de usuário não muda para os controles internos do ASP.Net

Force o logon e escreva o nome dele codificando.

Autenticado
        if (HttpContext.Current.User.Identity.IsAuthenticated)
            lblUserName.Text = HttpContext.Current.User.Identity.Name;


Logout

Session.Abandon();
FormsAuthentication.SignOut()

Dependendo de como você cria o ticket mesmo que ele feche o Browser ele continuará logado.
Você já assistiu minha aulas sobre Forms Authentication e Roles, eu mostro como fazer sem utilizar os assistentes.

Espero ter ajudado.

Fabio










Até aí tudo bem, a página correta é aberta, mas tem um problema: o browser não é redirecionado propriamente dito para a página, e sim ela é aberta no mesmo local, sendo que são passados alguns parâmetros pela string de URL automaticamente pelo ASP.Net. O segundo efeito colateral que pude observar é que, mesmo que o usuário ao tentar acessar uma página na qual não tem permissão, ser redirecionado novamente � página de login, efetuar o login corretamente para o novo usuário, o nome de usuário não muda para os controles internos do ASP.Net, pois ao tentar saber qual o usuário que está logado ele informa o primeiro usuário que fez logon e não o último, apesar do controle de acesso �s pastas funcionar perfeitamente.

Quero que uma aplicação possua login de usuário, sem usar os componentes prontos.

O que eu fiz, e não está funcionando corretamente:

Tenho as pastas: pastaA, pastaB e pastaC.

Uma página de login: default.aspx.

No web.config, coloquei a instrução:
<authentication mode="Forms">
      <forms name="Autenticação" loginUrl="Default.aspx" path="/" timeout="30" slidingExpiration="true" cookieless="AutoDetect" protection="All" />
    </authentication>

Quando o usuário digita o login e a senha, faço as verificações de praxe, e dependendo do tipo de usuário, quero que ele seja redirecionado para uma determinada pasta dentre as 3 citadas acima (A, B ou C).

Se o usuário puder acessar a pastaA, não pode acessar a pastaB e pastaC, a mesma lógica vale para as demais.

Para fazer esse controle, utilizei a ferramenta ASP.Net Configuration (menu Project ASP.Net Configuration do Visual Studio) e criei 3 usuários: usuarioA, usuarioB e usuarioC. Em seguida, criei 3 funções (Roles): usuarioA, usuarioB e usuarioC, atribuindo � cada função o usuário correspondente.

O próximo passo foi criar um web.config em cada pasta, com o seguinte código:
<configuration>
  <system.web>
    <authorization>
      <deny users="?" roles="usuarioB,usuarioC" />
      <allow roles="usuarioA"/>
    </authorization>
  </system.web>
</configuration>

Esse web.config foi copiado para demais pastas e ajustado conforme cada uma para terem as configurações corretas.

Pois bem, a priori, o sistema de segurança funciona, pois o usuário autenticado não consegue acessar as pastas que não sejam a autorizada para o seu acesso. No entanto, o código só funciona adequadamente quando o usuário tenta acessar a página previamente, ou seja, antes de fazer o login, usando o código FormsAuthentication.RedirectFromLoginPage("usuarioA", false).

Para contornar esse problema, ao invés do código acima, utilizei o seguinte:
FormsAuthentication.SetAuthCookie("usuarioA", false);
                    Server.Transfer("~/usuarioA/usuarioA.aspx");

Até aí tudo bem, a página correta é aberta, mas tem um problema: o browser não é redirecionado propriamente dito para a página, e sim ela é aberta no mesmo local, sendo que são passados alguns parâmetros pela string de URL automaticamente pelo ASP.Net. O segundo efeito colateral que pude observar é que, mesmo que o usuário ao tentar acessar uma página na qual não tem permissão, ser redirecionado novamente � página de login, efetuar o login corretamente para o novo usuário, o nome de usuário não muda para os controles internos do ASP.Net, pois ao tentar saber qual o usuário que está logado ele informa o primeiro usuário que fez logon e não o último, apesar do controle de acesso �s pastas funcionar perfeitamente.

Enfim, esse relato foi apenas para citar o que já fiz. Resumidamente, o que eu preciso é:
Ter 3 usuários distintos que devem acessar 3 pastas distintas dentro da aplicação. Cada usuário não pode ver as outras duas pastas da qual ele não tem autorização.
Quero, a partir da página principal, no momento que usuário fizer logon, seja redirecionado para a página correta, sem necessidade de ter que tentar acessar a página antes.
Não há necessidade de usar o que eu fiz e comentei acima. O importante é funcionar!
Responder

Gostei + 0

17/08/2009

Celso Paganelli

Fábio, muitíssimo obrigado por sua resposta.
Assisti suas aulas e solucionaram meu problema totalmente.
Inclusive, através dos seus vídeos descobri a ferramenta CodeRush, que é muito útil!

Grande abraço!
Responder

Gostei + 0

17/08/2009

Fabio Mans

Não conheço, o que faz o CodeRush?
Responder

Gostei + 0

17/08/2009

Fabio Mans

Ele deve fazer o mesmo trabalho do ReSharper, que é o que eu utilizo

Fabio
Responder

Gostei + 0

17/08/2009

Celso Paganelli

Acabei de ver o ReSharper. Aparentemente eles fazem mais ou menos a mesma coisa (CodeRush). Mas o ReSharper é bem mais barato. Valeu pela dica novamente!

Celso
Responder

Gostei + 0

17/08/2009

Celso Paganelli

Fábio, acabei de ver um aviso que dá ao compilar o código do seu exemplo:

Warning    1    The given expression is never of the provided ('System.Web.Security.FormsAuthentication') type

Ele dá o aviso na seguinte linha, do Global.asax:

if (HttpContext.Current.User.Identity is FormsAuthentication)

Não afeta em nada a aplicação, mas seria interessante "corrigir" o código. O erro me parece estar relacionado ao objeto ser do tipo Generic. Pesquisei na internet, mas não achei nada conclusivo.

[]s

Celso
Responder

Gostei + 0

18/08/2009

Fabio Mans

Não localizei.



  protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    FormsIdentity id =
                        (FormsIdentity)HttpContext.Current.User.Identity;
                    FormsAuthenticationTicket ticket = id.Ticket;
                    string userData = ticket.UserData;
                    string[] roles = userData.Split(',');
                    HttpContext.Current.User = new GenericPrincipal(id, roles);
                }
            }
        }
    }
Responder

Gostei + 0

25/08/2009

Devmedia

Celso,
a resposta foi esclarecida, podemos encerrar o chamado?
Responder

Gostei + 0

04/09/2009

Devmedia

Celso,
por falta de retorno estamos encerrando o chamado. Caso ainda tewnha dúvidas sobre o assunto aqui tratado, por favor, volte a postar aqui mesmo que o consultor voltará a lhe atender.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar