Utilización de grupos en Spring Security

22
61218

Utilización de grupos en Spring Security

0.
Índice de contenidos

1.
Introducción

En este primer tutorial que realizo en Autentia vamos a ver, con
un sencillo ejemplo, como se configura Spring Security para controlar
el acceso a los recursos de una aplicación, por medio de la
asignación de roles a grupos de usuarios, los cuales se podrán
modificar desde una base de datos.

Spring
Security
es un subproyecto del framework
Spring, que permite gestionar completamente la seguridad de
nuestras aplicaciones Java, y cuyas ventajas principales son las
siguientes:

  • Es capaz de gestionar seguridad en varios niveles: URLs que
    se solicitan al servidor, acceso a métodos y clases Java, y
    acceso a instancias concretas de las clases.

  • Permite separar la lógica de nuestras aplicaciones del
    control de la seguridad, utilizando filtros para las peticiones al
    servidor de aplicaciones o aspectos para la seguridad en clases y
    métodos.

  • La configuración de la seguridad es portable de un
    servidor a otro, ya que se encuentra dentro del WAR o el EAR de
    nuestras aplicaciones.

  • Soporta muchos modelos de identificación de los
    usuarios (HTTP BASIC, HTTP Digest, basada en formulario, LDAP,
    OpenID, JAAS y muchos más). Además podemos ampliar
    estos mecanismos implementando nuestras propias clases que extiendan
    el modelo de Spring Security.

2.
Herramientas utilizadas

Este tutorial ha sido desarrollado en Windows Vista, y para su
elaboración se han utilizado las siguientes herramientas:

3.
Creando una aplicación de prueba

Creamos un nuevo proyecto web dinámico. Podemos darle el
nombre que queramos, en mi caso lo he llamado “PruebaSeguridad”.

Vamos a seleccionar el Target Runtime pulsando sobre el botón
new.

Seleccionamos como servidor Apache Tomcat 6.

Seleccionamos la ruta donde tenemos instalado el tomcat, en mi
caso “C:\Program Files\Apache Software
Foundation\apache-tomcat-6.0.18”, y pulsamos finalizar.

Vamos a crear tres sencillas páginas jsp de prueba dentro
de la carpeta WebContent.

En la primera, “index.jsp”, mostraremos un menú
con dos opciones. Cada opción redirigirá a una de las
otras dos páginas, a las cuales restringiremos el acceso más
adelante por medio de Spring Security.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>




Inicio


        

Indice

Listado de villancicos

Administracion

El contenido de las otras dos páginas podría ser
cualquiera. En “villancicos.jsp”, ya que se acerca la
Navidad, mostraremos una lista con algunos villancicos populares, un
enlace para poder volver al índice y otro para salir (y poder
volver a identificarnos en la aplicación).

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>





Listado de villancicos


        

Listado de villancicos

Titulo Popularidad
Los peces en el río 90
Campana sobre campana 95
La marimorena 97

Volver al indice

Salir

La url “j_spring_security_logout” será capturada
por el interceptor de Spring Security una vez que lo hayamos
configurado, y permitirá hacer logout al usuario, de forma que
si intenta acceder de nuevo a un recurso protegido, se le volverán
a solicitar los datos de identificación.

En la página de administración, mostraremos un
mensaje, un enlace para volver al índice y otro para salir.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>





Administracion


        

¡Estás en la página de administración!

Volver al indice

Salir

Por último, para comprobar que todo funciona correctamente,
ejecutamos nuestra pequeña aplicación en el Tomcat y
desde un navegador probamos su funcionamiento.

4.
Creando una base de datos para gestionar los usuarios, grupos y roles

Creamos un nuevo esquema de base de datos, utilizando una consola
del sistema. Deberemos utilizar un usuario con permiso para crear
nuevos esquemas en la base de datos.

Para crear el esquema utilizaremos la sentencia: “create
schema seguridad;”.

Para crear las tablas hemos utilizado los siguientes scripts.

create table users(
      username varchar(50) not null primary key,
      password varchar(50) not null,
      enabled boolean not null);
      
create table authorities (
      username varchar(50) not null,
      authority varchar(50) not null,
      constraint fk_authorities_users foreign key(username) references users(username));
      
create unique index ix_auth_username on authorities (username,authority);

create table groups (
  id bigint auto_increment primary key,
  group_name varchar(50) not null);
  
create table group_authorities (
  group_id bigint not null, 
  authority varchar(50) not null, 
  constraint fk_group_authorities_group foreign key(group_id) references groups(id));

create table group_members (
  id bigint auto_increment primary key,
  username varchar(50) not null,
  group_id bigint not null,
  constraint fk_group_members_group foreign key(group_id) references groups(id));

NOTA: para que el servidor pueda encontrar el driver de MySql habrá
que añadir el conector (“mysql-connector-java.jar”)
a la carpeta de librerías del Tomcat (“%TOMCAT_DIR%\lib”).

5.
Configurando Spring para controlar la seguridad de nuestra aplicación

Antes de nada, deberemos añadir dentro de “WebContent/lib”
al menos las siguientes librerías, que se incluyen con Spring
y Spring Security:

Creamos el fichero de configuración para Spring Security,
dentro de la carpeta WEB-INF, al que llamaremos
“applicationContext-security.xml”. El esqueleto básico
será el siguiente:






Configuramos los interceptores de Spring Security, y establecemos los
permisos adecuados para nuestras páginas:

  • La página de índice no tendrá
    restringido el acceso.

  • La página de administración tendrá el
    acceso restringido a los usuarios que tengan el rol “ROLE_ADMIN”.

  • El resto de páginas estarán restringidas a
    usuarios con el rol “ROLE_USER”.


            
            
            
            
            
            
                  
    

Spring Security aplicará la lista de interceptores en el orden
en que aparece. Cuando encuentre un patrón adecuado, aplicará
los permisos correspondientes y no continuará leyendo el resto
de interceptores. Por tanto es importante colocar primero los filtros
más específicos y después los más
generales.

Además indicamos que nos muestre una página de login
y el tipo de autenticación que vamos a utilizar, así
como la página a la que se debe redirigir al hacer logout.

A continuación configuramos el AuthenticationProvider, que
utilizará como UserService una de las implementaciones que
vienen con Spring Security: JdbcDaoImpl. Esta implementación
nos permite configurar los permisos de los usuarios en una base de
datos a la que se accederá por medio de un DataSource.


        
    
            
            
    

La propiedad “enableGroups” permite activar el uso de
grupos para controlar la seguridad. Es importante cambiar el valor de
esta propiedad si queremos utilizar grupos de seguridad, ya que por
defecto vale false.

Añadimos el DataSource, indicando el usuario, contraseña
y la URL a nuestro esquema de base de datos.


Por último debemos editar la configuración del fichero
“web.xml” y añadir las siguientes líneas.


        contextConfigLocation
        /WEB-INF/applicationContext-security.xml



        org.springframework.web.context.ContextLoaderListener



        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy



        springSecurityFilterChain
        /*

El parámetro de contexto “contextConfigLocation”
indica la ruta o rutas de los ficheros de configuración de
Spring. En nuestro caso indicamos la ruta del fichero de
configuración creado anteriormente.

El ContextLoaderListener se encargará de cargar los
ficheros de configuración de Spring indicados en
“contextConfigLocation”.

El filtro de seguridad es el encargado de manejar las peticiones
que se hagan a todas las URLs para permitir o no el acceso de acuerdo
a los permisos que hayamos establecido en el fichero de
configuración.

Ahora podemos volver a arrancar nuestro servidor para probar los
cambios. Al intentar acceder al listado de villancicos o a la página
de administración se nos redirige a una página de
login. Todavía no podremos acceder a estas páginas, ya
que no hemos creado ningún usuario con los roles adecuados.

6.
Añadiendo usuarios, grupos y roles

Ahora que ya está configurada nuestra aplicación de
prueba, solamente nos queda añadir los usuarios, grupos y
roles a la base de datos.

Añadimos los siguientes usuarios a la tabla USERS:

username   password   enabled
-----------------------------
'enrique' 'enrique' 1
'juan' 'juan' 1
'lucas' 'lucas' 0
'pepe' 'pepe' 1
'rosa' 'rosa' 1

Añadimos los siguientes grupos a la tabla GROUPS:

id   group_name
----------------------
1 'usuarios'
2 'administradores'
3 'invitados'

A continuación podemos dar roles a los grupos, añadiendo
los siguientes registros en la tabla GROUP_AUTHORITIES, que relaciona
roles con grupos. En nuestro ejemplo hemos añadido un único
rol a cada grupo, pero es posible asignar n roles a cada uno. El
grupo ‘invitados’ no tiene ningún rol asignado, por lo que los
usuarios que pertenezcan a él no tendrán permisos
definidos y no podrán acceder a los recursos protegidos.

group_id   authority
--------------------
1 'ROLE_USER'
2 'ROLE_ADMIN'

Por último, añadimos los usuarios a los grupos, desde
la tabla GROUP_MEMBERS, que relaciona grupos con usuarios. Cada
usuario podrá pertenecer a varios grupos y sus roles efectivos
serán la unión de los roles de cada grupo a los que
pertenezca.

id  username   group_id
-----------------------
2 'lucas' 2
3 'juan' 1
4 'rosa' 3
5 'enrique' 2
6 'pepe' 1
8 'enrique' 1

De esta forma los usuarios “juan” y “pepe”
pertenecerán al grupo “usuarios”, mientras que
“lucas” pertenecerá al de “administradores”.
“rosa” pertenece al grupo invitados, que no tiene
asignado ningún permiso, mientras que “enrique”
pertenece tanto al grupo de administradores como al de usuarios.

Efectivamente, no hemos utilizado la tabla AUTHORITIES para nada.
Esta tabla permite asignar roles directamente a los usuarios, pero en
nuestro caso hemos preferido realizar esta asignación a través
de los grupos. No obstante, todavía podríamos asignar
permisos directamente a los usuarios si utilizamos esta tabla, de
forma que el usuario tendría la suma de sus permisos más
los que tengan los grupos a los que pertenece. Si queremos
deshabilitar la asignación de permisos directamente a los
usuarios (es decir que no se tenga en cuenta la tabla AUTHORITIES)
tendremos que asignar el valor false a la propiedad
“enableAuthorities” de nuestro UserService:


    
    
    

La propiedad “enableAuthorities” toma el valor true por
defecto, al contrario que “enableGroups”. Es importante
dejar al menos una de las dos propiedades (enableGroups o
enableAuthorities) a true, ya que de lo contrario obtendremos un
error de configuración de Spring Security.

Podemos intentar entrar en la aplicación con los distintos
usuarios para ver si obtenemos el comportamiento esperado.

Vemos que cualquiera puede acceder a la página de indice,
incluso aunque no se haya identificado, pero cuando pulsamos en uno
de los enlaces se nos muestra la página de login.

Cuando probamos a acceder con el usuario “lucas” se
nos muestra un mensaje indicando que el usuario está
deshabilitado (está en inglés, ya que es un formulario
de login que implementado por defecto Spring Security).

Cuando probamos con “rosa” ocurre algo parecido, pero
esta vez el mensaje es diferente, ya que el usuario no tiene los
permisos adecuados.

Por último podemos comprobar que “juan” y
“pepe” pueden acceder solamente al listado de
villancicos, pero cuando intentan acceder a la página de
administración se muestra el siguiente error, ya que no tienen
permiso para acceder a la página.


El
único usuario al que se permite acceder a la página de
administración es “enrique”, ya que lo hemos
añadido al grupo de administradores.

7.
Conclusiones

A la vista de los resultados de este tutorial podemos sacar las
siguientes conclusiones:

  • Spring Security nos ofrece servicios de identificación
    y acceso a los recursos de nuestras aplicaciones de una forma
    potente y sencilla, sin tener que escribir ni una sola línea
    de código.

  • Podemos asignar los permisos directamente a los usuarios o a
    grupos de usuarios, o incluso mezclar ambas formas.

  • Podemos añadir fácilmente seguridad en nuestras
    aplicaciones existentes o modificar la seguridad de una aplicación
    rápidamente, ya que Spring Security separa claramente la
    seguridad de una aplicación de su lógica.

Y eso es todo. Desde autentia esperamos que este tutorial os haya
sido de utilidad y os ayude a gestionar la seguridad de vuestras
aplicaciones mediante Spring Security.

22 COMENTARIOS

  1. Buenas, este tutorial esta muy bueno, yo genere spring security en un proyecto de spring roo, pero no puedo cambiar la vista del login que me sale, ya intente cambiar el login.jspx que genera roo, pero no toma los cambios, tenes algun tipo de solucion? gracias.

  2. Donde se pueden descargar los ejemplos?, porque en realidad a este ejemplo le hace falta una gran parte del mvc, las clases y su configuracion para que pueda ser reconocido el userdetail…

  3. Hola jaider2523.
    En realidad al ejemplo le faltan muchas cosas para poder ser una aplicación real, pero se trata precisamente de eso, de un ejemplo sencillo que muestra cómo se pueden utilizar grupos en Spring Security. El código no está disponible, pero todas las clases y configuración necesarias están explicadas detalladamente en el tutorial. No se necesita nada más para que funcione este ejemplo; si no me crees, compruébalo tú mismo.
    En este ejemplo se usa \\\»org.springframework.security.userdetails.jdbc.JdbcDaoImpl\\\», por tanto no necesitamos definir un UserDetailService personalizado.
    Saludos.

  4. hola soy Pablo de Argentina y quería saber como puedo desarrollar este mismo sistema de autenticación de miembros y roles, pero usando Netbeans 6.9.1, este sistema se llama Membership en Asp.Net y me gusto mucho su uso, lo que quiero ahora es hacerlo pero en Java por Netbeans, si alguien me puede ayudar se lo agradeceria

  5. Si vas a usar Spring Security, puedes seguir este tutorial, independientemente del IDE que utilices (Netbeans, Eclipse, bloc de notas…). Espero haber resuelto tu duda.
    Saludos.

  6. Hola, muy bueno el tutorial, pero tengo un problema. No consigo recuperar despues del login los datos del usuario, nada mas acceder lo intento desde una clase @Controller con String usuario = req.getParameter(«j_username»);. Lo que quiero es a traves del usuario que se ha logado identificar a que cliente pertenece, almacenarlo en un objeto session y utilizarlos posteriormente para querys. Muchas gracias

  7. Hola Enrique, muy bueno el tutorial, pero mi consulta va por el caso de «enrique» que como mencionaste, tiene dos tipos de accesos o «perfiles». ¿Cómo enlazo la selección del perfil de acceso(ya que tiene mas de uno) luego del login y antes de ir a una vista de «bienvenida»?. Agradeceria tu respuesta. Saludos desde Perú

  8. Hola Saby, gracias por tu comentario.

    El usuario enrique no tiene dos tipos de acceso, lo que tiene son dos roles diferentes. Esto le permitirá acceder a páginas securizadas para cualquiera de ellos. No necesita cambiar de rol, siempre tendrá los dos.

    Espero haber aclarado tu duda.

    Saludos desde España 😉

    • Gracias por responder Enrique.
      Mi pregunta por los «roles» va en el sentido de que mi menú esta determinado por el tipo de rol que tiene el usuario :; entonces lo que necesito es que la vista se forme solo por uno de los roles, determinado por el perfil de acceso seleccionado en una vista previa (no se si me explico).

      Usuaio-> (Varios (perfil-rol)).

      El problema surge cuando el GrantedAuthorities toma por defecto el ultimo rol creado para el usuario; y por mas que cambie de perfil, no cambia el rol; por lo que, por ejemplo, la vista me queda con los accesos del ADMINISTRADOR y no de ALUMNO.

      Lo que quisiera saber es como hago para cambiar el rol seleccionado por defecto.

      Espero que me puedas responder.
      Saludos 🙂

  9. Hola estoy tratando de implementar con spring security 2 conexiones diferentes ldap y mysql segun el domino seleccionado en el jsp de login.

    pero estoy teniendo problemas con implementar esta dinamica.

    si me pudieran apoyar si ya les toco trabajar con algo asi.

    saludos.

  10. Hola Enrique, mi pregunta es la siguiente, estoy desarrollando un sistema de ventas al cual se accede con un usuario y contrasenia, una vez que accedo al sistema y luego lo cierro y otra persona intenta entrar teniendo una url despues de acceder al sistema entra normal ya sin que se loguee….no se si mee dejo enteneder..osea que teniendo una url que esta despues de acceder al sistema puedo acceder sin que me haya logueado para entrar…como puedo solucionar esto por favor…

    • Hola Álvaro.

      Cuando dices que lo cierras, ¿significa que cierras la ventana, el navegador?. Siempre deberías hacer logout. En el ejemplo que pongo hay un enlace salir que llama a ‘j_spring_security_logout’. De esa forma se cerraría la sesión y ya no dejaría entrar sin hacer login de nuevo, aunque tengamos la URL.

      Si quieres que al cerrar la ventana se haga logout automáticamente podrías hacerlo por medio de javascript, aunque si no es un requisito del cliente yo no te lo recomendaría.

      Un saludo.

  11. Hola . Gracias por esta información . Solo me surgio una duda ya que en otros sitios mencionan que tienes que estar desarrollando con Spring para poder usar Spring security pero aqui no veo que sea necesario … Yo estoy en un desarrollo con sql Server y puros JSP , no hay nada de frameworks … Aún así se puede usar ?

    • Hola Mario.

      Sí estamos utilizando Spring en este tutorial. Si te fijas, en el web.xml configuramos el Listener para cargar el contexto de Spring. Pero podrías utilizarlo solamente para controlar la seguridad, como aquí, si no necesitas utilizarlo para nada más.

  12. Hola!

    Forzosamente necesitas crear esas tablas para el manejo de roles y permisos?, qué pasa si no quieres hacer uso de un formulario de logueo… Saludos!

    • Hola Luis.

      Las tablas que he configurado en el ejemplo son las que utiliza por defecto la implementación del UserDetails: org.springframework.security.userdetails.jdbc.JdbcDaoImpl. Podrías configurarlo para utilizar otras distintas.
      Es más, puedes utilizar otro UserService diferente para obtener los permisos de un LDAP, un fichero de texto o tu propia implementación…

      Tampoco estás obligado a usar un formulario de logueo, aunque si necesitas autenticación tendrás que configurar algún otro mecanismo.

      Te recomiendo consultar la documentación de Spring Security (que ya van por una versión bastante más nueva que cuando se escribió este tutorial).
      http://docs.spring.io/spring-security/site/docs/4.0.4.RELEASE/reference/htmlsingle/#what-is-acegi-security

      Un saludo.

  13. Buen Dia.

    Estoy desarrollando una aplicacion con spring, maven, hibernate, spring security, tengo el login contra mi base de datos y funciona de maravilla, ahora quiero agregar un link en mi pagina de login para una nueva jsp donde estara el registro de nuevos usuarios, pero al momento de hacer click sobre el link este no me lleva a la nueva pagina, si no que me carga de nuevo la pagina de login, creo que esta aplicando seguridad y no me resuleve el link, quisiera saber como puedo decirle que me de acceso tambien a la pagina de registro de usuarios? o si hay alguna forma de crear un registro de usuarios con spring security?

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad