Problemas entre Spring 3.0 y Spring Web Flow 2.0.8

Tags: , , ,

Hace unos dias intentando integrar Spring Security 3.0 con Spring Web Flow en su última version 2.0.9 al día de hoy, como en el ejemplo siguiente.

   <bean id="securityFlowExecutionListener" class="org.springframework.webflow.security.SecurityFlowExecutionListener" />
 
   <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
        <webflow:flow-execution-listeners>
            <webflow:listener ref="securityFlowExecutionListener" />
        </webflow:flow-execution-listeners>
    </webflow:flow-executor>

Esta configuracion en Web Flow basicamente lo que hace es que podamos restringir ciertas vistas o flujos enteros en base a Roles con Spring Security

 <secured attributes="ROLE_USER"/>
 
<view-state id="main">
        <on-render>
            <render fragments="zona3"/>
        </on-render>
        <transition on="paso1" to="reviewHotels">
              <secured attributes="ROLE_EDITOR"/>
             <evaluate expression="bean.metodo1()" />
             <render fragments="zona1"/>
        </transition>
        <transition on="paso2" >
              <secured attributes="ROLE_ADMIN"/>
             <evaluate expression="bean.metodo2() />
             <render fragments="zona1"/>
        </transition>
    </view-state>

y obtenia este error al compilar.

Caused by: java.lang.ClassNotFoundException: org.springframework.security.vote.AffirmativeBased
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
... 65 more

Pero parece no tener solución por ahora salvo que tu apliques el parche publicado en JIRA hace unos dias.

Aunque hoy mismo publicaron que el parche saldria hasta la versión Spring Web Flow 2.1 y no en la 2.0.9 como hace 48 horas estaba publicado.

https://jira.springsource.org/browse/SWF/fixforversion/11441

En pocas palabras, a esperar.

Configurando Spring Security 3.0 y actualizando con Maven

Tags: , ,

Vamos con algo sencillo el día de hoy. Ante la llegada hace unos meses ya de Spring Security 3.0 y con estupendas novedades y sus cambios.

Si ya has migrado te habrás dado cuenta que muchos de los nombres de los paquetes han cambiado.

import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.openid.OpenIDAuthenticationStatus;
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;

antes se llamaban

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.openid.OpenIDAuthenticationStatus;
import org.springframework.security.openid.OpenIDAuthenticationToken;

No solo estas clases han cambiado, en mi migración de hace unos dias me encontre que con el 70% de las clases que usaba habian sido cambiadas, fue todo un dolor de cabeza al principio.

Nota: no te olvides de agregar los filtros en el web.xml eso no ha cambiado para nada en la 3.0.

Actualizando con Maven

Yo ahora mismo estoy trabajando con la versión 3.0.2.RELEASE y es bastante estable aunque tiene un bug con la integración en Spring Web Flow.

El uso de propiedades en Maven es muy recomendable, si mañana quieres actualizar a otra versión es mucho mas comodo cambiar en un solo lugar, existen muchos otros JAR disponibles en Spring Security como (CAS, ASL o Spring Web) que tambien puedes agregar como dependencia, segun tus necesidades.

 
 <properties>
    <spring.security.version>3.0.2.RELEASE</spring.security.version>
 </properties>
 
<dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>${spring.security.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>${spring.security.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-ldap</artifactId>
      <version>${spring.security.version}</version>
    </dependency>
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-openid</artifactId>
    <version>${spring.security.version}</version>
    <scope>compile</scope>
  </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-taglibs</artifactId>
      <version>${spring.security.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>${spring.security.version}</version>
</dependency>

Otra cosa que debes modificar o agregar si es una nueva configuración es en los namespaces.

 
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.0.xsd">
</beans>

Configuración Mínima

Spring Security 3.0 nos permite desde una configuración sencilla hasta las mas completas, según la documentacion esto es lo mínimo que necesitas.
En este caso se podria llamar una versión amateur de la configuración real con beans en Spring Security, ellos nos ofrecen este una version resumida de la configuracion, siendo la mínima lo siguiente

 
<http auto-config='true'>
  <intercept-url pattern="/**" access="ROLE_USER" />
</http>

Y pudiendose extender a algo mas complejo (complejo dentro de la sencille) como:

  <security:http auto-config="false"
                 entry-point-ref="authenticationEntryPoint"
                 access-decision-manager-ref="voteAccessDecisionManager" >
    <security:intercept-url pattern="/**" access="ENCUESTAME_ANONYMOUS" />
    <security:intercept-url pattern="/admon/**/*" access="ENCUESTAME_ADMIN" />
    <security:intercept-url pattern="/tweet/" access="ENCUESTAME_ANONYMOUS" />
    <security:intercept-url pattern="/" access="ENCUESTAME_ANONYMOUS" />
    <security:intercept-url pattern="/**/*.xhtml" filters="none" />
    <security:intercept-url pattern="/**/*.css"  filters="none" />
    <security:intercept-url pattern="/images/**" filters="none" />
    <security:intercept-url pattern="/js/**" filters="none" />
    <security:remember-me key="12345" services-alias="_rememberMeServices" />
    <security:anonymous key="12345" />
    <security:logout logout-success-url="/index.html" logout-url="/logout"/>
    <security:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
    <security:custom-filter position="ANONYMOUS_FILTER"  ref="anonymousAuthFilter" />
  </security:http>

Para aprender algo más sobre los multiples filtros que ofrece Spring Security en versiones anteriores, en este mismo blog postee algunos artículos.

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?

© 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.