Cómo crear el schema de la base datos con Anotaciones de Hibernate y Spring

Tags: , , , ,

A veces es necesario hacer cambios a nuestra base de datos, y siempre estaremos lidiando con las herramientas gráficas o desde la consola, con los cambios en la base de datos, pero existen formas de hacer este trabajo “sucio” mucho más rapido y ahorrando tiempo.

En nuestro caso, usaremos Spring 2.5 y Hibernate 3.3 y MySQL, donde es necesario ya tengas armado los beans de conexión a la base de datos. El siguiente código es un array de cadenas, si en nuestro caso tenemos segmentado los xml de spring, los añadiremos de la siguiente manera.

// array de string para agregar todos tus archivos de configuración de spring
private static final String[] SPRING_CONFIG_FILES =
new String[]{"source/spring/config/xxxxxx-db-context.xml", "source/spring/config/xxxxxxx-param-context.xml"};

A continuación, el código necesario para generar nuestra base de datos, el FileSystemXmlApplicationContext carga el Contexto de la Aplicación, y una vez teniendo el contexto obtenemos el SessionFactory, que en nuestro caso usamos Anotaciones, creamos el bean en base a la clase AnnotationSessionFactoryBean , esto es importante pues en base a esta clase usaremos los metodos dropDatabaseSchema(); para borrar el actual schema (tablas, relaciones , etc) y luego ejecutamos createDatabaseSchema(); para crear el nuevo schema.

// carga el application context de Spring
 FileSystemXmlApplicationContext appContext = new FileSystemXmlApplicationContext(SPRING_CONFIG_FILES);
// Obtiene el bean del session factory
 AnnotationSessionFactoryBean annotationSF = (AnnotationSessionFactoryBean)  appContext.getBean("&sessionFactory");
// si quieres eliminar el schema de la base de datos
 annotationSF.dropDatabaseSchema();
// para crear nuevamente el schema de la base de datos
 annotationSF.createDatabaseSchema();

Los archivos de configuración de Spring, deben lucir de la siguiente manera, hay que destacar el hibernate.dialect donde indicamos el dialecto que usaremos para crear el schema, en el caso de MySQL puede ser MySAM o InnoDB, luego el parametro hibernate.hbm2ddl.delimiter que también indicamos el tipo de tablas que usaremos en mi caso usaré type=InnoDB.

<bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${datasource.classname}" />
        <property name="url" value="${datasource.urldb}" />
        <property name="username" value="${datasource.userbd}" />
        <property name="password" value="${datasource.pass}" />
    </bean>
 
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
          <list>
              <value>Clase1</value>
              <value>Clase2</value>
          </list>
        </property>
        <property name="hibernateProperties">
           <props>
                <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
                <prop key="hibernate.dialect">${datasource.dialect}
                </prop>
                <prop key="hibernate.show_sql">${datasource.showsql}</prop>
                <prop key="hibernate.hbm2ddl.delimiter">${datasource.delimited}</prop>
            </props>
        </property>
      </bean>

Spring Security 2, la configuración a la medida con DAO Hibernate IV

Tags: , , ,

Más filtros de los que explicamos en el artículo anterior se puede usar en Spring Security, donde vimos los filtros esenciales para la configuración de nuestra capa de seguridad.

AnonymousProcessingFilter

Este filtro es muy util, nos permite darle acceso a un usuarios anónimos a secciones del sistema, digamos que la pagina de registro debe ser de acceso anónimo, en el FilterChainProxy agregamos otra linea donde colocamos el recurso y le asignamos el filtro, ese recurso sera accesible siempre y cuando en el FilterSecurityInterceptor también podemos hacer uso del Rol que indicamos que seran Roles para identificar al usuario anónimo.

<bean id="anonymousProcessingFilter"
		class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
		<property name="key">
			<value>MU7kyU0he1MvXEDZ9Mdj7MVvkXOXJ8uRgtg/Xb/3eJyW0HZa3csBoyvinGEC4vmi</value>
		</property>
		<property name="userAttribute">
			<value>anonymousUser,ENCUESTAME_ANONYMOUS
			</value>
		</property>
	</bean>

ExceptionTranslationFilter

Maneja cualquier AccessDeniedException y AuthenticationException arrojados dentro de la cadena de filtro. Este filtro es necesario, ya que proporciona el puente entre las excepciones de Java y las respuestas HTTP. Sólo se ocupan de mantener la interfaz de usuario. Este filtro no hace ninguna garantía real de la ejecución. Para utilizar este filtro, es necesario especificar las siguientes propiedades:

  • authenticationEntryPoint indica que el controlador debe comenzar el proceso de autenticación si un AuthenticationException se detecta. Tenga en cuenta que esto también puede cambiar el actual protocolo de http a https para un inicio de sesión SSL.
  • portResolver (opcional) Se utiliza para determinar el “verdadero” puerto por la que fue recibida la petición.
    • <bean id="exceptionTranslationFilter"
      		class="org.springframework.security.ui.ExceptionTranslationFilter">
      		<property name="authenticationEntryPoint">
      			<ref local="authenticationEntryPoint" />
      		</property>
      	</bean>

      BasicProcessingFilterEntryPoint

      Este filtro es responsable de la tramitación de cualquier solicitud que tiene un encabezado de petición HTTP Authorization con un sistema de autenticación Basica y una codificación username:password simbólico. Por ejemplo, para autenticar el usuario “Aladdin”, con contraseña “ábrete Sésamo” el siguiente encabezado se mostrara como el siguiente ejemplo, (Autorización: Básica QWxhZGRpbjpvcGVuIHNlc2FtZQ == ). Si la autorización es satisfactoria, el objetoAuthentication se colocará en el SecurityContextHolder.

      <bean id="authenticationEntryPoint" class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
        		<property name="realmName"><value>EmForge</value></property>
      </bean>

      LogoutFilter

      Se necesita una forma de cerrar sesión, el LogoutFilter es la solución perfecta, indicamos en el constructor del bean el lugar donde seremos dirigidos cuando cerremos la sesión, y una lista de beans o manejadores de Cerrar sesión, por defecto se debe usar el SecurityContextLogoutHandler, aunque puedes personalizar el tuyo propio.

      <bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
      	 <constructor-arg value="/pages/index.me" />
      		<constructor-arg>
      			<list>
      				<!--  <ref bean="rememberMeServices"/>  -->
      				<bean
      					class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />
      			</list>
      		</constructor-arg>

      AuthenticationProcessingFilterEntryPoint

      AuthenticationProcessingFilterEntryPoint, es el bean que nos redirecionará a la pantalla de la aplicación donde se inicia sesión, o a donde nosotros queramos por eso la propiedad loginFormUrl. En el caso en que los credenciales no sean correctos se utliza el objeto AccessDeniedHandlerImpl, y en su propiedad errorPage se le especifica a que camino se debe dirigir la aplicación en caso de error.

      <bean id="formEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
            	<property name="loginFormUrl" value="/login.faces"/>
         	</bean>

      Estos son los filtros más usados y que podemos aplicar a nuestra seguridad, junto con los explicados anteriormente son una magnifica opción para crear nuestra seguridad, y como ven, con muy poca programación. En el siguiente artículo veremos la integración del OPENID en Spring Security.

Spring Security 2, la configuración a la medida con DAO Hibernate III

Tags: , , , , ,

El dia de hoy vamos a continuar con los Filtros, es la parte central de la seguridad de Spring, y por eso la hace tan flexible, porque esta completamente separada del modelo de Negocio, eso es lo que lo hace tan genial, pues si el dia de mañana se te ocurre cambiar toda la seguridad, tu sistema no sufrirá grandes cambios.

Los filtros se encargan de la seguridad de la aplicación. Existen tres filtros fundamentales se encadenan juntos mediante un objeto llamado “filterChainProxy”, que crea e inicializa los tres filtros; como se ve en el siguiente diagrama.

filtrosacegi

  1. El filtro AuthenticationProcessingFilter maneja la petición o requerimiento (request) que chequea la autenticación -Authentication Request Check- (“el login de la aplicación”). Para ello usa el AuthenticationManager que vimos en el articulo anterior.
  2. El filtro HttpSessionContextIntegrationFilter mantiene el objeto Authentication entre varios requests y se lo pasa al AuthenticationManager y al AccessDecisionManager cuando sea necesario.
  3. El filtro ExceptonTranslationFilter verifica la existencia de autenticación , maneja las excepciones de seguridad y ejecuta la acción apropiada. El ExceptonTranslationFilter depende del filtro siguiente, FilterSecurityInterceptor.
  4. FilterSecurityInterceptor controla el acceso restricto a recursos determinados , y el chequeo de autorización.  Conoce qué recursos son seguros y qué roles tienen acceso a ellos.  FilterSecurityInterceptor usa el AuthenticationManager y el AccessDecisionManager para hacer su trabajo.

Cuando inicias, todo esto es una maraña de filtros sin sentido, pero vamos a profundizar un poco para que te quede más claro la funcion y configuración de cada uno de ellos.

AuthenticationProcessingFilter

El primer filtro donde pasa el RequestHTTP. Este filtro se especializa en manejar el request de autentificación, valida el usuario y la contraseña, más alla de esto solo debes conocer otros parametros imporantes.

  • authenticationFailureUrl: En el caso de fallo, algún lugar debe de ir cuando no se logea el usuario.
  • defaultTargetUrl: Es el URL por defecto, generalmente es la raiz.
  • filterProcessesUrl: Es a quien le encarga la responsbilidad de verificar si el usuario se logea o no..
<bean id="authenticationProcessingFilter"
		class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
		<property name="authenticationManager">
			<ref bean="authenticationManager" />
		</property>
		<property name="authenticationFailureUrl">
			<value>/login.me</value>
		</property>
		<property name="defaultTargetUrl">
			<value>/</value>
		</property>
		<property name="filterProcessesUrl">
			<value>/j_spring_security_check</value>
		</property>
	</bean>

HttpSessionContextIntegrationFilter

El HttpSessionContextIntegrationFilter es fácil de configurar. Su única función, es propagar por el Contexto de Seguridad la autenticación a través de todas las solicitudes. No necesita propiedades ni nada en especial.

<bean id="httpSessionContextIntegrationFilter"
		class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />

ExceptionTranslationFilter

El filtro ExceptionTranslationFilter intercepta cualquier error de autenticación o autorización, por ejemplo UsernameNotFoundException o DataAccessException.

Si la excepción fue causada por una excepción de autorización lanzada por el filtro FilterSecurityInterceptor (puede ser porque no tiene permisos para acceder a un Recurso Web, una imagen o un URL), el filtro lanzará un HTTP 403 al navegador, el cual mostrará una página de acceso no autorizado.

<bean id="formExceptionTranslationFilter"
		class="org.springframework.security.ui.ExceptionTranslationFilter">
		<property name="authenticationEntryPoint">
			<ref local="formEntryPoint" />
		</property>
	</bean>
 
<bean id="formEntryPoint"
		class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
		<property name="loginFormUrl" value="/login.me" />
	</bean>

FilterSecurityInterceptor

El FilterSecurityInterceptor, es donde protegeremos todos nuestros recursos, donde decidimos que ROL entra a ciertos recursos, cuales pueden ser accedido por usuarios anónimos, todo esto se configura en el objectDefinitionSource. Necesitamos 2 referencias para configurar este Filtro, el authenticationManager y el bean accessDecisionManager que miraremos en el siguiente artículo.

<bean id="filterInvocationInterceptor"
		class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
		<property name="authenticationManager" ref="authenticationManager" />
		<property name="accessDecisionManager" ref="voteAccessDecisionManager" />
		<property name="objectDefinitionSource">
			<value>
				CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
				PATTERN_TYPE_APACHE_ANT
				/=ENCUESTAME_ANONYMOUS
				/pages/**=ENCUESTAME_USER
				/pages/admon/**=ENCUESTAME_ADMIN
				/user/**=ENCUESTAME_ANONYMOUS,ENCUESTAME_USER,ENCUESTAME_ADMIN
         </value>
		</property>
	</bean>

FilterChainProxy

El filtro inicializador, su función principal es indicar o personalizar, que recursos ejecutaran los filtros deseados en filterInvocationDefinitionSource, por ejemplo, si tenemos un sevlet /uploadFile y solo nos interesa aplicar algunos filtros

<bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
      <property name="filterInvocationDefinitionSource">
         <value>
		   CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
		    PATTERN_TYPE_APACHE_ANT
               /**=httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,authenticationProcessingFilter....
              /uploadFile= basicProcessingFilter,OtroFiltroPersonalizado
         </value>
      </property>
    </bean>

En el siguiente artículo, veremos una extensión de los diferentes filtros opcionales que podemos integrar en nuestra seguridad, ¿preguntas?

  • Autor: admin
  • Publicado: May 13th, 2009
  • Categoria: Articulos
  • Comentarios: 1

Spring Security 2, la configuración a la medida con DAO Hibernate II

Tags: , , , , ,

Siguiendo con el articulo anterior, voy a explicar los diferentes Filtros de Seguridad y las Configuraciones Personales que podemos aplicar en nuestra Seguridad. El siguiente gráfico explica el ciclo de vida de la autentificación en Spring.

En el post anterior, vimos el Bean del Formulario de logeo, donde se creo el objeto Authentication que se pasa al AuthenticationManager.

UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(userName, password);
.......
Authentication auth = getAuthenticationManager().authenticate(authReq);

spring_exception_filter

AuthenticationManager

El bean AuthenticationManager es del tipo ProviderManager, lo que significa que actúa de proxy con AuthenticationProvider. En Spring, el AuthenticationProvider es el encargado de validar la combinación nombre de usuario/contraseña por medio del objeto Authentication  y retornar los roles asociados a dicho usuario. Esta clase tan sólo delega la autenticación en una lista de proveedores configurable, cada uno de los cuales implementa el interfaz AuthenticationProvider. Hay muchos tipos de AuthenticationProvider( JDBC, Hibernate,  LDAP, RememberMe, OpenID). Usted puede indicar cuales quiere usar son los proveedores de autentificación que desee usar, en nuestro caso, usaremos un DAO Hibernate personalizado.

<bean id="authenticationManager" class="paquete.MiAuthenticationManager">
	<property name="providerString" value="userDaoProvider" />
</bean>
public class MiAuthenticationManager extends ProviderManager {
protected String providerString;
public void setProviderString(String providerString) {
		this.providerString = providerString;
	}
 /**
  * Agrega al Manejador de Proveedores un listado
  */
public void afterPropertiesSet() throws Exception {
		if (providerString != null) {
			List<authenticationprovider> providers = new LinkedList();
			String[] names = providerString.split(",");
			for (String providerUnit : names) {
				AuthenticationProvider provider = (AuthenticationProvider) applicationContext
						.getBean(providerUnit.trim());
				if (provider == null) {
 
					throw new EnMeExpcetion("AuthenticationProvider "
							+ providerUnit + " don't exist");
				}
				providers.add(provider);
			}
			setProviders(providers);
		}
		super.afterPropertiesSet();
	}
}
 
</authenticationprovider>

DaoAuthenticationProvider

DaoAuthenticationProvider, es el comúnmente usado puesto que es el que permite acceder a la información almacenada en una base de datos. El proveedor DaoAuthenticationProvider merece una mención especial. Esta implementación delega a su vez en un objeto de tipo UserDetailsService, un interfaz que define un objeto de acceso a datos con un único método loadUserByUsername que permite obtener la información de un usuario a partir de su nombre de usuario.

<bean id="userDaoProvider"
		class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
		<property name="userDetailsService" ref="dbUserService" />
	</bean>

Si deseas agregarle encriptación a la contraseña del usuario, agregale una propiedad más al userDaoProvider, este artículo que escribi tiempo atrás te ayudará a poner una mejor seguridad que el tipico MD5.

UserDetailsService, un Dao Personalizado

Si no queremos que Spring acceda a la bases de datos directamente podemos configurar un Dao personalizado por medio de una Implementación UserDetailsService, , un interfaz que define un objeto de acceso a datos con un único método loadUserByUsername que permite obtener la información de un usuario a partir de su nombre de usuario.

 
<bean id="dbUserService" class="paquete.MiUserServiceImp">
		<property name="userDao" ref="userDao" />
	</bean>


public class MiUserServiceImp implements UserDetailsService {
         ......
        public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		SecUsers user = userDao.getUser(username);
		if (user == null) {
			log.info("no encontrado...");
			throw new UsernameNotFoundException("username");
		}
		return convertToUserDetails(user);
	}
 
         ......
 
    protected UserDetails convertToUserDetails(SecUsers user){
         //lista de permisos,
         List<string> listPermissions = new ArrayList</string><string>();
        ...........
        GrantedAuthority[] authorities = new GrantedAuthority[listPermissions
				.size()];
		int i = 0;
		for (String permission : listPermissions) {
			authorities[i++] = new GrantedAuthorityImpl(permission.trim());
		}
 
		User userDetails = new User(user.getUsername(), user.getPassword(),
				user.isStatus() == null ? false : user.isStatus(), true,
				true,
				true,
				authorities);
		log.info("userDetails "+userDetails);
		return userDetails;
    }
}
</string>

Vamos a dejar la explicación de los Filtros, para una tercera parte, ya se hizo largo :) .

© 2009 Jotadeveloper Blog. Nuestros contenidos están bajo licencia Creative Commons mientras no se indique lo contrario,
y pueden reproducirse libremente sin más que mencionar la fuente ("JotaDeveloper") y la URL concreta del artículo original. .

This blog is powered by Wordpress and JotaDeveloperTheme.