Conceptos Básicos de Spring Security

Spring Security es el framework de autenticación y control de acceso de Spring.

Autenticación en el caso más usual es determinar que el usuario que accede al sistema es quien dice ser. Spring soporta muchísimas formas de hacer la autenticación y van desde la más básica que es un simple formulario HTML hasta otras como OpenID, CAS, LDAP, Kerberos, JAAS, etc.

Control de acceso es determinar si un usuario puede realizar una determinada acción dentro del sistema. En muchos casos no tiene sentido realizar el control de acceso usuario por usuario sino agrupando a todos los usuarios que pueden realizar las mismas acciones dentro del sistema. Es decir, no se define “María y Roberto pueden imprimir facturas” sino, “todos los usuarios que sean vendedores pueden imprimir facturas”. Si hoy Juan es encargado de limpieza entonces no puede imprimir facturas, pero el día de mañana, Juan podría ser ascendido a área de ventas y ser vendedor, por lo que entonces sí podrá imprimir facturas. La forma de agrupar a “todos los usuarios que sean vendedores” es mediante roles. Entonces en un momento sólo María y Roberto tienen el rol “ROLE_VENDEDOR” y posteriormente se agregará Juan a ese grupo asignándole dicho rol.

Entender que un rol no es otra cosa que un conjunto de usuarios es muy importante.

Spring permite controlar el acceso en tres niveles

  1. URLs de una aplicación WEB,
  2. métodos de un Bean de Spring.
  3. objetos del dominio.

La única diferencia entre las tres es qué operación es la que se está controlando.

En el primer caso, se busca controlar el acceso a un grupo de recursos que son identificables mediante una URL. Por ejemplo si nuestra aplicación web tiene una página que sólo debe ser accedida por un gerente y no por todos los demás empleados, una estrategia sería que la URL de esa página fuera por ejemplo “/gerencia/index.jsp” y se configurara Spring Security para que sólo usuarios con rol “ROLE_GERENTE” pudieran acceder a URLs que empezaran con “/gerencia”.

El segundo caso busca controlar la ejecución de un método en particular. Se usa en situaciones donde no se trata de una aplicación web, cuando no es posible tener URLs distintas para diferenciar el acceso o cuando independientemente de qué URL fue solicitada desde el cliente queremos asegurarnos de que no se ejecute un método si no se trata del usuario que tiene el permiso. Los métodos que pueden ser controlados son métodos de objetos que sean Beans de Spring, no cualquier objeto.

El tercer caso busca controlar el acceso a objetos de dominio. El ejemplo más claro es para extraer dinero de una cuenta bancaria. Se debe verificar que el usuario sea el dueño de esa cuenta en particular y la relación de quién es dueño de qué cuenta puede ir variando en el tiempo por ejemplo a medida que se agregan o quitan titulares. En este caso los objetos que se desean controlar no tienen que ser Beans de Spring, puede ser cualquier objeto.

Para resolver el tercer caso se usa un módulo de Spring Security que se llama Domain Object Security o Spring ACLs.

Con Spring ACLs se define para cada objeto (instancias individuales) del dominio que se necesite controlar una lista de usuarios y roles que pueden accederlo. Como un rol no es otra cosa que un conjunto de usuarios, en verdad lo que se indica para cada objeto del dominio es directa o indirectamente una lista de usuarios.

Gráficamente lo que se tiene es un objeto del dominio, como por ejemplo una cuenta bancaria:

{Cuenta 123541500542}

y asociada al objeto una lista de usuarios que están autorizados a sacar dinero de esa cuenta

{Cuenta 123541500542} -> {“Juan”, “Pedro”, “Susana”}

Cuando la aplicación está por realizar la operación de débito sobre esa cuenta debemos indicarle a SpringSecurity que verifique que el usuario que está realizando la operación esté en la lista de usuarios de la cuenta sobre la que se está operando.

¿Cómo sería esto con la intervención de roles? Supongamos que existiera en el sistema un rol “ROLE_GERENTE_DE_CUENTAS” y que de acuerdo a las reglas del banco un usuario con ese rol está autorizado a realizar débitos sobre cualquier cuenta. La ACL quedaría así

{Cuenta 123541500542} -> {“Juan”, “Pedro”, “Susana”, “ROLE_GERENTE_DE_CUENTAS”}

Spring Security verificará en el momento que le sea indicado si el usuario que está intentando realizar la operación es Juan, Pedro, Susana, o algún usuario que tenga asignado el rol “ROLE_GERENTE_DE_CUENTAS”. Nuevamente,  como un rol no es otra cosa que un conjunto de usuarios en la lista la presencia de un rol es sólo una forma indirecta de referirnos a usuarios.

Si en cambio se define a los roles como un conjunto de “operaciones” o un conjunto de “permisos” es más difícil entender qué hace el rol en la lista de usuarios autorizados y por lo tanto entender cómo adaptar Spring ACLs a nuestra aplicación.

Spring ACLs es muy flexible y potente ya que permite manejar varios permisos como lectura, escritura, borrado y además permite otorgar y revocar permisos. Por ejemplo si le otorgamos permiso al rol “ROLE_GERENTE” y se lo revocamos al usuario “Juan” que  tiene ese rol, lo que logramos es definir que todos los gerentes menos “Juan” tienen otorgado el permiso. También podría ser a la inversa y definiríamos que ningún gerente tenga permiso a excepción de “Juan”. Si vemos los roles  como conjuntos de usuarios, es simplemente quitar elementos del conjunto.

Para aprender más en detalle cómo usar Spring ACLs, se pueden consultar estos dos artículos

Windows 7 Menos Seguro que Vista por Omisión

Windows 7 incorpora una mejora al mecanismo de control de acceso del usuario al sistema (UAC). El objetivo es reducir la cantidad de veces que aparece la ventana pidiendo confirmación y el resultado es que Windows 7 es menos seguro que Vista. ¿Por qué?

Ahora hay una lista de programas que no requieren autorización para adquirir permisos de administrador. Esos programas son por ejemplo la calculadora y el bloc de notas. De esa forma cuando se abre un archivo de sistema con el bloc de notas, nos ahorramos la ventana de confirmación. El problema es que existe una funcionalidad documentada en Windows que permite a cualquier programa ejecutar código como si fuera otro (como el bloc de notas) y por lo tanto es posible para cualquier programa adquirir permisos de administrador sin pedirle confirmación al usuario. En la práctica significa que con la configuración por omisión de Windows 7 toda confirmación es irrelevante, porque un programa malicioso puede no pedir jamás confirmación y obtener los permisos.

La única solución es poner el control en el nivel máximo, lo que revierte el comportamiento a como era en Vista y prohíbe a cualquier programa adquirir permisos de administrador sin pedir confirmación, incluyendo el bloc de notas. Así sí es seguro, pero pregunta a cada rato.

Microsoft dice que la ventanita de confirmación no es una medida de seguridad (a pesar de que su ícono es un escudo) y hace notar que ahora Windows y el Internet Explorer tienen más medidas de seguridad que nunca.

La triste realidad es que Windows no puede encontrar una forma de ser seguro sin hacer que dejen de funcionar muchos programas porque tiene años de tradición y legado dándole a todo usuario control total sobre el sistema y en versiones previas directamente ignorando la separación entre usuarios.

Hay un video mostrando cómo se puede escalar privilegios usando Windows 7: http://leo.lss.com.au/W7E_VID_INT/W7E_VID_INT.htm

Y varios artículos en la prensa describiendo el tema: