Segurança em páginas JSP

Veja neste artigo sobre segurança em páginas JSP como podemos proteger a nossa aplicação web.

JavaServer Pages e Servlets possuem vários mecanismos disponíveis para desenvolvedores web protegerem seus aplicativos. Resources são seguros declarativamente por meio de verificações no descritor de implantação de aplicativos e atribuindo um papel a eles.

Vários níveis de recursos estão disponíveis, que vão desde a autenticação básica usando login e senha para autenticação sofisticada usando certificados.

Autenticação baseada na Role (Role Based Authentication):

O mecanismo de certificação da especificação Servlet usa um mecanismo chamado segurança baseada em funções(Role Based Authentication). Essa idéia é que ao invés de limitar os recursos a nível de usuário, criamos papéis e restringimos os recursos dos papéis.

Nós podemos definir diferentes papéis no arquivo de tomcat-users.xml, que é colocado no diretório home do Tomcat em conf. Segue abaixo um exemplo:

Listagem 1: Definindo diferentes papéis

<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="manager"/> <role rolename="admin"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="role1" password="tomcat" roles="role1"/> <user username="both" password="tomcat" roles="tomcat,manager"/> <user username="admin" password="secret" roles="admin,role1"/> </tomcat-users>

Este arquivo define um mapeamento entre o nome de usuário, senha e papel. A preocupação de que um determinado usuário pode ter mais de uma função, por exemplo, nome de usuário = "fulano" está no papel "tomcat" e a função "role1".

Uma vez identificados e definidos diferentes papéis, limitações de segurança podem ser colocados em diferentes recursos de aplicativos da Web usando o elemento no arquivo web.xml presente no diretório WEB-INF.

Listagem 2: exemplo de entrada web.xml

<web-app> ... <security-constraint> <web-resource-collection> <web-resource-name> SecuredBookSite </web-resource-name> <url-pattern>/secure</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description> Only admin can use this app </description> <role-name>admin</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>role1r</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> </login-config> ... </web-app>

O código acima quer dizer que:

Agora, se nós tentarmos navegar para qualquer URL incluindo o diretório /security, ele iria mostrar uma caixa de diálogo solicitando nome de usuário e senha. Se nós fornecemos um usuário "admin" e a senha "securer", então só teríamos acesso a URL acompanhado por /secured/ * porque acima de nós definimos usuário admin com a função de gerente, que tem permissão para acessar este recurso.

Formulário baseado em autenticação:

Quando usamos o método de formulário baseado em autenticação, deve ser fornecido um formulário de login para solicitar ao usuário um login e senha. A seguir está um código simples de loginpage.jsp para criar um formulário para o mesmo fim:

Listagem 3: Código simples de loginpage.jsp

<html> <body bgcolor="#ffffff"> <form method="POST" action="j_security_check"> <table border="0"> <tr> <td>Login</td> <td><input type="text" name="j_username"></td> </tr> <tr> <td>Password</td> <td><input type="password" name="j_password"></td> </tr> </table> <input type="submit" value="Login!"> </center> </form> </body> </html>

Aqui nós temos que ter certeza de que o formulário de login deve conter elementos de formulário chamado j_username e j_password. A ação no deve ser j_security_check. O formulário dece usar um método GET.

Ao mesmo tempo em que teria de modificar a tag para especificar auth-method como FORM:

Listagem 4: Código auth-method

<web-app> ... <security-constraint> <web-resource-collection> <web-resource-name> SecuredBookSite </web-resource-name> <url-pattern>/secured/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <description> Let use this app only by managers </description> <role-name>manager</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>manager</role-name> </security-role> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/loginpage.jsp</form-login-page> <form-error-page>/errorpage.jsp</form-error-page> </form-login-config> </login-config> ... </web-app>

Agora, quando tentar acessar qualquer recurso com a URL /secured/ *, será exibido acima formulário pedindo login de usuário e senha. Quando o servidor ver a ação "j_security_check", segue-se um mecanismo interno para verificar o usuário chamador.

Se a autenticação for bem sucedida e o usuário estiver autorizado a acessar o recurso protegido, o servidor usa uma sessão-id para identificar uma sessão de login para o usuário a partir desse ponto. O servidor mantém a sessão de login com um cookie contendo o id da sessão. O servidor retorna o cookie de volta para o cliente, e enquanto o chamador existe este cookie com pedidos frequentes, o servidor vai saber quem é o usuário chamador.

Se o login falhar, o servidor envia de volta a página identificada pela definição de form--página de erro.

Aqui j_security_check é a ação que aplicativos usando formulário baseado em sessão tem que especificar para o formulário de login. Na mesma forma, temos um controle de entrada de texto chamado j_username e um controle de entrada de senha chamado j_password. Quando vemos isso significa que as informações contidas no formulário serão armazenadas no servidor, que irá verificar o login e a senha.

Segurança programática em um Servlet/JSP:

O objeto HttpServletRequest fornece os métodos abaixo, que podem ser usados para obter informações de segurança em tempo de execução:

Método Descrição
String getAuthType() O método getAuthType () resulta um objeto String que representa o nome do esquema de autenticação usado para proteger o Servlet.
boolean isUserInRole(java.lang.String role) O método isUserInRole () retorna um valor booleano: true se o usuário possui determinado role e false se eles não possuem.
String getProtocol() O método getProtocol () retorna um objeto String representando o protocolo que foi usado para enviar a requisição. Este valor pode ser determinado de modo que, se um protocolo de segurança foi utilizado.
boolean isSecure() O método IsSecure () retorna um valor booleano representando se a solicitação foi criada usando HTTPS.
Principle getUserPrinciple() O método getUserPrinciple () resulta java.security.Principle um objeto que contém o nome do usuário autenticado atual.

Listagem 5: Demonstração do método getAuthType

import java.util.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.security.*; public class MyServlet extends HttpServlet { public void init(ServletConfig cfg) throws ServletException { super.init(cfg); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>"); out.println("User Authentication"); out.println("</TITLE>"); out.println("</HEAD>"); out.println("<BODY>"); out.println("<H1>User Authentication</H1>"); String type = request.getAuthType(); out.println("Welcome User<BR>"); out.println("Authentication mechanism: " + type + "<BR>"); Principal p = request.getUserPrincipal(); out.println("Wer username is: " + p.getName() + "<BR>"); out.println("</BODY>"); out.println("</HTML>"); } }

Saída:

Welcome User
Authentication mechanism:Manager
Wer username is:Davi

Por exemplo, uma JSP com links para páginas de gestores pode ter o seguinte trecho:

Listagem 6: Link para gestores

<% if (request.isUserInRole("manager")) { %> <a href="managers/mgrreport.jsp">Manager Report</a> <a href="managers/personnel.jsp">Personnel Records</a> <% } %>

Ao verificar o papel do usuário em um JSP ou Servlet, podemos personalizar a página da Web para mostrar ao usuário apenas os itens que podem ser usados. Se precisarmos do nome do usuário podemos chamar o método getRemoteUser no objeto da requisição.

Conclusão

Tecnologia de segurança de Java inclui um grande conjunto de APIs, ferramentas e cumprimento de algoritmos de segurança utilizados, protocolos e mecanismos. As APIs de segurança do Java abrange uma ampla gama de áreas, incluindo a infra-estrutura de chave pública, criptografia e autenticação, comunicação fixa e controle de uso. Tecnologia de segurança de Java confere ao programador com uma estrutura de segurança completa para aplicações de escrita, e também concede o usuário ou administrador um conjunto de ferramentas para gerenciar com segurança as aplicações.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados