La seguridad de los recursos de las aplicaciones web puede ser controlada de 2 formas diferentes:

  • A través del contenedor (mecanismos integrados).
  • Mediante la propia aplicación web (mecanismos de login).

  • Apache Tomcat permite incorporar seguridad por medio de Container Managed Security (seguridad basada en contenedores) sobre Realms.

    Un Realm (dominio) es una colección (“base de datos”) de usuarios, contraseñas y roles (=grupos de linux) que Tomcat administra y utiliza para gestionar la autenticación a través de una interfaz (*) . Una aplicación web puede declarar qué recursos serán accesibles, y por cuáles grupos de usuarios, en su archivo de configuración web.xml. El administrador de Tomcat podrá configurar usuarios, contraseñas y roles utilizando estas implementaciones de Realms y estos privilegios definidos podrán ser utilizados por varias aplicaciones web.

    Los tags principales que se utilizan para declarar los parámetros de seguridad sobre el fichero web.xml son:

    • <security-constraint>: especifica la seguridad de acceso a los recursos de la aplicación que serán las carpetas y sus contenidos.

    • <login-config>: especifica el tipo de autenticación (BASIC, FORM)
      • BASIC , no es necesario definir un formulario de login ya que apache Tomcat se encarga de ejecutar una llamada a una ventana de autenticación de nuestro navegador web. La autenticación perdurará hasta que cerremos nuestro navegador web .

      • FORM , la aplicación debe incorporar un formulario HTML diseñado específicamente, utilizando unas reglas de diseño determinadas, para que Tomcat lo ejecute cuando se intente acceder a recursos privilegiados. La autenticación perdurará hasta que se destruya la sesión (session.invalidate()) .

    UserDatabaseRealm es la interfaz Realm más conocida. Los permisos (usuarios, contraseñas y roles) son cargados en memoria, una sola vez al arrancar el servidor, desde un archivo estático y mantenidos en memoria hasta que Tomcat se detenga. El archivo por defecto para asignar permisos de una interfaz UserDatabaseRealm es tomcat-users.xml , localizado en el directorio $CATALINA_HOME/conf .

    Este tipo de “base de datos” de usuarios se recomienda para aplicaciones pequeñas que tienen un número reducido de usuarios.

    Pasos para la implementación de Realm UserDatabaseRealm , con autenticación BASIC, sobre una aplicación web existente:

    Fichero /tomcat/conf/tomcat-users.xml Configurar los usuarios y roles. Hay que reiniciar Apache Tomcat tras realizar cualquier cambio en este fichero.
    
    <?xml version='1.0' encoding='utf-8'?>
    
    <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0">
    
    <!-- Tomcat manager -->
    <role rolename="manager-gui"/>
    <role rolename="admin"/>
    <user name="admin" password="admin" roles="manager-gui,admin"/>
    <!-- Definir los roles -->
    <role rolename="teacher"/>
    <role rolename="student"/>
    <!-- Crear un usuario con 1 rol "student" -->
    <user username="usuario" password="usuario" roles="student"/>
    <!-- Crear un usuario con 2 roles "teacher" y "student" -->
    <user username="jaserrano" password="jaserrano" roles="teacher,student"/>
    </tomcat-users>
    
    Fichero /WEB-INF/web.xml de la aplicación web

    Indicar los recursos protegidos.

    • Indicar los recursos protegidos añadiendo un tag <security-constraint>

    • Tag <url-pattern> indicamos los recursos que necesitarán autenticación.

    • Tag <auth-constraint> define los roles de usuarios que tendrán acceso los ficheros del directorio protegido.
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    
    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <session-config>
    <session-timeout>35</session-timeout>
    </session-config>
    <security-constraint>
    <display-name>Acceso solo para profesores</display-name>
    <web-resource-collection>
    <web-resource-name>Zona <url-pattern>/privado/*</url pattern>
    </web-resource-collection>
    <auth-constraint>
    <role-name>teacher</role-name>
    </auth-constraint>
    </security-constraint>
    <security-constraint>
    <display-name>Acceso para alumnos</display-name>
    <web-resource-collection>
    <web-resource-name>Zona compartida</web-resource-name>
    <url-pattern>/publico/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
    <role-name>student</role-name>
    </auth-constraint>
    </security-constraint>
    <login-config>
    <auth-method>BASIC</auth-method>
    </login-config>
    </web-app>
    

    Fichero /WEB-INF/web.xml de la aplicación web

    Tipo de autenticación (BASIC).

    Autenticación de tipo BASIC por lo que se abrirá una ventana de autenticación de nuestro navegador web.

    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    
    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    ...
    ...
    <login-config>
    <auth-method>BASIC</auth-method>
    </login-config>
    </web-app>
    

    Pasos para la implementación de Realm UserDatabaseRealm, con autenticación FORM, sobre una aplicación web existente:

    1. login.jsp y error.jsp

    Se utiliza un formulario de login personalizado que no depende del navegador web. Este formulario debe cumplir algunas características para que se pueda comunicar correctamente con el subsistema de autenticación Apache Tomcat.

    CONFIGURACIÓN OBLIGATORIA

    action='j_security_check' : URL del Servlet, integrado en Tomcat, encargado de validar el usuario y contraseña contra la “base de datos” de Realm.

    method='POST' : por seguridad nunca se usa GET.

    name='j_username' : nombre que espera el Servlet.

    type='password' : para que no sea visible al introducirse.

    name='j_password' : nombre que espera el Servlet.

    type="submit" : botón tipo SUBMIT.

    
    	login.jsp
    
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <form name='login' action='${pageContext.request.contextPath}/j_security_check' method='POST'> User:<br> <input type='text' name='j_username'><br> Pass:<br> <input type='password' name='j_password'><br>
    <input name="submit" type="submit" value="Acceder">
    </form>
    </body>
    </html>
    
    

    Debajo del mismo formulario de login añadimos un mensaje de error.

    CONFIGURACIÓN OBLIGATORIA

    action='j_security_check' : URL del Servlet, integrado en Tomcat, encargado de validar el usuario y contraseña contra la “base de datos” de Realm.

    method='POST' : por seguridad nunca se usa GET.

    name='j_username' : nombre que espera el Servlet.

    type='password' : para que no sea visible al introducirse.

    name='j_password' : nombre que espera el Servlet.

    type="submit" : botón tipo SUBMIT.

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    
    	error.jsp
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Error</title>
    </head>
    <body>
    <form name='login' action='${pageContext.request.contextPath}/j_security_check' method='POST'> User:<br> <input type='text' name='j_username'>
    <br>Pass:<br> <input type='password' name='j_password'><br>
    <input name="submit" type="submit" value="Acceder">
    </form>
    <DIV align="center">
    <font color="red"> User or Pass incorrect!
    </font>
    </DIV>
    </body>
    </html>
    

    2. Fichero /WEB-INF/web.xml de la aplicación web

    Tipo de autenticación (FORM).

    
    <?xmlversion="1.0"encoding="UTF-8"?>
    <web-appversion="3.1"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    
    ...
    ...
    
    	<login-config>
    		<auth-method>FORM</auth-method>
    		<form-login-config>
    			<form-login-page>/login.jsp</form-login-page>
    			<form-error-page>/error.jsp</form-error-page>
    		</form-login-config>
    	</login-config>
    </web-app>