Seguridad en nuestra aplicación con Servlet Filter
En mi anterior entrada os comentaba que para ver un ejemplo de cookies, habíamos hecho una pequeña aplicación en la que teníamos una pagina de login que al autenticarse, creábamos una cookie para indicar que estábamos autorizados para navegar por la aplicación.
01 Cookie miCookie = new Cookie( "logged", "true" ); 02 miCookie.setMaxAge( 60*60*24 ); 03 response.addCookie( miCookie );Con este código, creamos la cookie para saber que estamos autenticados. Entonces para poder proteger todas las páginas de la aplicación o todas las peticiones que hagamos al servidor, tendremos que comprobar que la cookie que nos indica que estamos autorizados esta creada y con el valor correcto,y en el caso de que no estemos autorizados dirigirlo a la pantalla de login.
01 Cookie[] cookies = request.getCookies(); 02 boolean logged = false; 03 04 if( cookies != null ) { 05 for( int i=0; i < cookies.length; i++ ) { 06 Cookie cookieActual = cookies[i]; 07 String identificador = cookieActual.getName(); 08 String valor = cookieActual.getValue(); 09 10 if( identificador.equals( "logged" ) && valor.equals( "true" ) ) { 11 logged = true; 12 } 13 } 14 } 15 if( !logged ) { 16 request.getRequestDispatcher( "/login.jsp" ).forward( request, response ); 17 }Con este código hacemos la comprobación de que el usuario esta autorizado, el problema es que tendremos que repetir en cada página o petición a un servlet la comprobación de las cookies.
Existe otra manera de centralizar la comprobación de las cookies para ver si el usuario ha pasado por el proceso de autorización, y no tener que preocuparnos cada vez que creemos una página nueva. En las aplicaciones de servidor con Java EE, existe un componente que son unos filtros. Estos filtros se activan antes de ejecutar en el servidor un servlet o un path concreto dentro de nuestra aplicación web. Para configurar un filtro lo que haremos sera crear una clase que implemente el interface javax.servlet.Filter y mediante anotaciones indicar su nombre y una ruta a filtrar.
01 @WebFilter(filterName="Security", urlPatterns={"/*"}) 02 public class Security implements FilterEn el ejemplo que he puesto se crea una clase que implementa el interface javax.servlet.Filter, le llamamos Security y hacemos que se active para cualquier llamada a algún recurso de nuestra aplicación mediante '/*', cualquier ruta ha partir del raiz de nuestra aplicación web.
Cuando se activa nuestro filtro, se llama a la función definida en el interface 'doFilter(ServletRequest request, ServletResponse response, FilterChain chain)'. Los parámetros de este método son los mismos que recibiríamos en un servlet( request y response ) y ademas el objeto FilterChain, que lo utilizaremos para que la petición al servidor siga su camino y se ejecute normalmente. Pueden existir definidos más de un filtro, los cuales se irán ejecutando uno detrás de otro hasta terminar con la ejecución de la petición al servidor.
01 @WebFilter(filterName="Security", urlPatterns={"/*"}) 02 public class Security implements Filter 03 { 04 private FilterConfig filterConfig = null; 05 06 public Security() { 07 } 08 09 @Override 10 public void doFilter( ServletRequest request, ServletResponse response, 11 FilterChain chain ) throws IOException, ServletException 12 { 13 Cookie[] cookies = ((HttpServletRequest)request).getCookies(); 14 boolean logged = false; 15 16 if( cookies != null ) { 17 for( int i=0; i < cookies.length; i++ ) { 18 Cookie cookieActual = cookies[i]; 19 String identificador = cookieActual.getName(); 20 String valor = cookieActual.getValue(); 21 22 if( identificador.equals( "logged" ) && valor.equals( "true" ) ) { 23 logged = true; 24 } 25 } 26 } 27 if( !logged ) { 28 request.getRequestDispatcher( "/login.jsp" ).forward( request, response ); 29 } else { 30 chain.doFilter(request,response); 31 } 32 } 33 34 @Override 35 public void destroy() { 36 } 37 38 @Override 39 public void init(FilterConfig filterConfig) { 40 this.filterConfig = filterConfig; 41 } 42 }Como se puede ver en el código, el cuerpo del método doFilter es el mismo que poníamos al principio de esta entrada pero añadiéndole la linea chain.doFilter(request,response);. Con esta linea, si la autentificación ha ido bien, indicamos que continué con el siguiente filtro o realice la petición que se ha hecho al servidor. De esta manera solo hemos creado el código de verificación de usuario en el filtro, cada vez que llamemos a algún recurso de nuestra aplicación se ejecutara el filtro y comprobaremos si el usuario esta autorizado. Ya no necesitamos preocuparnos de repetir el código en todas las páginas o servlets que creemos nuevos.
Otra cosa que podríamos hacer, sería hacer que el filtro solo actuara en parte de nuestra aplicación web, de esta manera tendríamos parte visible a cualquiera y otra parte solo disponible a usuarios autorizados.
Por ejemplo se pueden definir los servlets privados de la siguiente manera
01 @WebServlet(name="Login", urlPatterns={"/private/users"}) 02 public class Login extends HttpServletAquí definimos un servlet dentro de 'private', entonces lo que haremos es definir el filtro para los recursos dentro de private
01 @WebFilter(filterName="Security", urlPatterns={"/private/*"}) 02 public class Security implements FilterAhora hemos definido el filtro para lo que se encuentre definido en 'private'.
0 comentarios:
Publicar un comentario
Suscribirse a Enviar comentarios [Atom]
<< Inicio