Autenticação
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.
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
Curtidas 0
Respostas
Fabio Mans
07/08/2009
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!
GOSTEI 0
Celso Paganelli
07/08/2009
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!
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!
GOSTEI 0
Fabio Mans
07/08/2009
Não conheço, o que faz o CodeRush?
GOSTEI 0
Fabio Mans
07/08/2009
Ele deve fazer o mesmo trabalho do ReSharper, que é o que eu utilizo
Fabio
Fabio
GOSTEI 0
Celso Paganelli
07/08/2009
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
Celso
GOSTEI 0
Celso Paganelli
07/08/2009
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
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
GOSTEI 0
Fabio Mans
07/08/2009
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);
}
}
}
}
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);
}
}
}
}
GOSTEI 0
Devmedia
07/08/2009
Celso,
a resposta foi esclarecida, podemos encerrar o chamado?
a resposta foi esclarecida, podemos encerrar o chamado?
GOSTEI 0
Devmedia
07/08/2009
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.
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.
GOSTEI 0