Você está na página 1de 6

Autenticao e Autorizao [CMS]

Publicado por jjocenio em 13/09/2010 - 61.946 visualizaes

comentrios: 14

O que quero mostrar nesse artigo como utilizar filtros para fazer autenticao em sistemas web. O uso dos filtros torna as verificaes de segurana mais simples pois todas so feitas em um s lugar. Sendo assim, vamos criar um site web com algumas reas de acesso restrito usurios com previlgios especficos. Ento, Mos a obra! Este tutorial est disponvel tambm no meu blog http://runningjava.blogspot.com OBS.: No utilizaremos struts nem internacionalizao pois esses assuntos esto fora do escopo desse artigo. Pra comear, vamos definir o mapa do site e as regras de acesso de cada uma delas. Criaremos um site com a seguinte estrutura:

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.

* Raz o index.jsp o logon.jsp o user_common.jsp o user_manager.jsp o user_admin.jsp o style.css o restrict + index.jsp o WEB-INF + classes # runningjava * article1 o User.java o LogonServlet.java o LogoffServlet.java o SecurityFilter.java # access.properties

Teremos 3 regras para os usurios: simple, manager e admin. As restries de acesso para as reas do site so:

1. * index.jsp, logon.jsp e style.css so pblicas, qualquer visitante tem acesso; 2. * user_common.jsp pode ser acessada por todos os usurios cadastrados; 3. * user_manager.jsp s poder ser acessada por usurios que t 4. enham as regras manager ou admin; 5. * user_admin.jsp de acesso exclusivo para os usurios que 6. tenham a regra admin; 7. * o diretrio restrict s pode ser acessado por usurios 8. cadastrados, com qualquer regra.

No arquivo access.properties colocaremos as regras de acesso todas as reas do site. O formato do arquivo de ser:

1.

recurso=regra1, regra2, regra3, ...

No nosso caso, teremos:

1. 2. 3. 4.

/user_common.jsp=simple, manager, admin /user_manager.jsp=manager, admin /user_admin.jsp=admin /restrict=simple, manager, admin

O prximo passo criar o filtro. Para isso criaremos a classe runningjava.article1.SecurityFilter que implementa a interface javax.servlet.Filter. Nessa classe implementaremos 4 mtodos para fazer o nosso trabalho de autenticao: init, doFilter, getNextURL e verifyAccess. Sendo que os dois primeiros so da interface Filter e os dois ltimos so por nossa conta. O mtodo init chamado pelo container para configurar o filtro. nele que carregaremos as regras de acesso s reas restritas do site. O que faremos carregar o arquivo access.properties em um objeto Properties e depois passar o contedo para um Map (isso opcional. podemos trabalhar diretamente com o Properties.

1. 2. 3. 4. 5. 6. 7. 8.

public void init(FilterConfig config) throws ServletException { try { String accessFile = this.getClass() .getClassLoader() .getResource("access.properties") .getPath(); Properties properties = new Properties();

9. 10. 11. 12. 13. 14. 15. 16.

properties.load(new FileInputStream(accessFile)); resources.putAll(properties); } catch (Exception e) { e.printStackTrace(); throw new ServletException(e); } }

O outro mtodo da inteface Filter o doFilter. Ele chamado pelo container quando um request tenta acessar um recurso que bate com o padro do filtro. nesse mtodo que faremos a verificao das regras de acesso. Basicamente, iremos verificar se o usurio logado detem as regras necessrias para acessar o recurso, se no enviamos ele pra pgina de login.

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { boolean allowed = verifyAccess((HttpServletRequest) request); if (!allowed) { String logon = "logon.jsp?next=" + getNextURL((HttpServletRequest) request); ((HttpServletResponse) response).sendRedirect(logon); } chain.doFilter(request, response); }

Como voc deve ter observado, ns utilizamos os mtodo verifyAccess e getNextURL. O mtodo verifyAccess verifica se o recurso que est sendo requisitado tem acesso restrito e se o usurio que est logado tem permisso para cess-lo. Se tudo isso for verdadeiro, o mtodo retorna true. Caso contrrio retorna false.

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.

protected boolean verifyAccess(HttpServletRequest request) { String resource = request.getRequestURI() .replaceAll(request.getContextPath(), ""); while (resource.length() > 0) { String rules = (String) resources.get(resource); if (rules != null) { User user = (User) request.getSession().getAttribute(User.KEY); return (user != null && user.hasRules(rules)); } else if (!resource.equals("/")) { int index = resource.lastIndexOf("/"); if (index > -1) {

13. 14. 15. 16. 17. 18. 19. 20. 21.

resource = resource.substring(0, index); } } else { resource = ""; } } return true; }

O mtodo getNextURL retorna a URL que estava sendo requisitada. Utilizamos esse recurso para passar ao logon para que, uma vez logado, o usurio possa ir diretamente para o recurso que ele tinha requisitado.

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

protected String getNextURL(HttpServletRequest request) { String url = request.getRequestURI(); StringBuffer params = new StringBuffer(""); Enumeration enumParams = request.getParameterNames(); while (enumParams.hasMoreElements()) { String name = (String) enumParams.nextElement(); String value = request.getParameter(name); if (params.length() > 0) { params.append("&"); } params.append(name).append("=").append(value); } return url + "?" + params.toString(); }

Pronto! Terminamos o nosso filtro. O que precisamos agora definir o servlet de logon e logoff. Para isso, criaremos duas novas classes runningjava.article1.LogonServlet e runningjava.article1.LogoffServlet, ambas extendem a classe javax.servlet.http.HttpServlet. Nas duas, precisaremos implementar o mtodo doService e no servlet de logon implementaremos tambm um mtodo logon. Esse mtodo (logon) recebe como parmetros o nome do usurio e a senha e, se encontrar, retorna o usurio. Caso contrrio retorna null e assim saberemos que o logon falhou. Servlet de logon.

1. 2. 3. 4. 5.

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter(USERNAME); String password = request.getParameter(PASSWORD);

6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.

String next = request.getParameter(NEXT); if (next == null || next.length() == 0) { next = "/index.jsp"; } User user = logon(username, password); if (user != null) { request.getSession().setAttribute(User.KEY, user); response.sendRedirect(next); } else { response.sendRedirect("logon.jsp?next=" + next + "&fail=1"); } }

Servlet de logoff.

1. 2. 3. 4. 5. 6.

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getSession().setAttribute(User.KEY, null); response.sendRedirect("/index.jsp"); }

O prximo passo agora preparar a tela de logon. Esse bastante simples. Precisamos somente de um form com um nome de usurio, uma senha e um campo hidden para armazenar a prxima url a ser chamada. Sendo assim, o arquivo logon.jsp fica assim:

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.

<form action="logon" method="post"> <input name="next" value="<%=request.getParameter("next")%>" type="hidden"/> <table align="center" border="0" cellpadding="4" width="50%"> <tr> <td align="right"> username </td> <td align="left"> <input name="username" type="text"> </td> </tr> <tr> <td align="right"> password </td>

16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.

<td align="left"> <input name="password" type="password"> </td> </tr> <tr> <td colspan="2" align="center"> <input value="logon" type="submit"> <input value="clear" type="reset"> </td> </tr> </table> </form>

Agora s nos falta configurar o contexto para reconhecer os servlets o chamar o filtro devidamente. Isso bastante simples. No arquivo web.xml colocamos as seguintes tags:

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.

<filter> <filter-name>SecurityFilter</filter-name> <filter-class>runningjava.article1.SecurityFilter</filter-class> </filter> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>LogonServlet</servlet-name> <servlet-class>runningjava.article1.LogonServlet</servlet-class> </servlet> <servlet> <servlet-name>LogoffServlet</servlet-name> <servlet-class>runningjava.article1.LogoffServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LogonServlet</servlet-name> <url-pattern>/logon</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LogoffServlet</servlet-name> <url-pattern>/logoff</url-pattern> </servlet-mapping>

Terminado. Agora temos um site com verificao de regras de acesso usando filtros. Espero que esse tutorial lhe seja bastante til.[/b]

Você também pode gostar