sesiones - spring security xml
Iniciar sesión/cerrar sesión en REST con Spring 3 (1)
Sugeriría que defina sus filtros Spring Security completamente de forma manual. No es tan difícil, y usted tiene control total sobre su comportamiento de inicio de sesión / cierre de sesión.
En primer lugar, necesitará la publicidad web.xml estándar para delegar el manejo de la cadena de filtros a Spring (eliminar async-supported si no está en Servlet API ver 3):
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<async-supported>true</async-supported>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Ahora, en el contexto de seguridad, definirá los filtros por separado para cada ruta. Los filtros pueden autenticar al usuario, cerrar la sesión del usuario, verificar las credenciales de seguridad, etc.
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/login" filters="sif,wsFilter"/>
<sec:filter-chain pattern="/logout" filters="sif,logoutFilter" />
<sec:filter-chain pattern="/rest/**" filters="sif,fsi"/>
</sec:filter-chain-map>
</bean>
El XML anterior le dice a Spring que pase las solicitudes a URLs contextuales específicas a través de cadenas de filtros. Lo primero en cualquiera de las cadenas de filtros es establecer un contexto de seguridad: ''sif'' bean se encarga de eso.
<bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
El siguiente filtro en la cadena ahora puede agregar datos al contexto de seguridad (léase: usuario de inicio / final de sesión) o tomar una decisión sobre si se permite el acceso en función de dicho contexto de seguridad.
Para su URL de inicio de sesión, necesitará un filtro que lea los datos de autenticación de la solicitud, los valide y, a su vez, los almacene en contexto de seguridad (que se almacena en la sesión):
<bean id="wsFilter" class="my.own.security.AuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="myAuthSuccessHandler"/>
<property name="passwordParameter" value="pass"></property>
<property name="usernameParameter" value="user"></property>
<property name="postOnly" value="false"></property>
Puede usar Spring genérico UsernamePasswordAuthenticationFilter
pero el motivo por el que uso mi propia implementación es continuar el proceso de cadena de filtrado (la implementación predeterminada asume que el usuario será redireccionado al finalizar satisfactoriamente la autenticación y termina la cadena de filtros) y poder procesar la autenticación cada vez que se pasa el nombre de usuario y la contraseña lo:
public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return ( StringUtils.hasText(obtainUsername(request)) && StringUtils.hasText(obtainPassword(request)) );
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException{
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
Puede agregar cualquier número de sus propias implementaciones de filtro para / ruta de inicio de sesión, como la autenticación mediante HTTP auth header, digest header, o incluso extraer username / pwd del cuerpo de la solicitud. Spring proporciona un montón de filtros para eso.
Tengo mi propio controlador de éxito de autenticación que anula la estrategia de redirección predeterminada:
public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
@PostConstruct
public void afterPropertiesSet() {
setRedirectStrategy(new NoRedirectStrategy());
}
protected class NoRedirectStrategy implements RedirectStrategy {
@Override
public void sendRedirect(HttpServletRequest request,
HttpServletResponse response, String url) throws IOException {
// no redirect
}
}
}
No es necesario que tenga un controlador de autenticación auth personalizado (y probablemente también un filtro de autenticación personalizado) si está de acuerdo con que el usuario sea redirigido después de iniciar sesión correctamente (la URL de redireccionamiento puede personalizarse, consultar documentos)
Defina el administrador de autenticación que será responsable de recuperar los detalles del usuario:
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="myAuthAuthProvider"/>
</sec:authentication-manager>
<bean id="myAuthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="myUserDetailsImpl"/>
</bean>
</property>
</bean>
Deberá proporcionar su propia implementación de bean de detalles de usuario aquí.
Filtro de cierre de sesión: responsable de borrar el contexto de seguridad
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg>
<list>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
Genérico de autenticación:
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>
Filtro de control de acceso (debe ser autoexplicativo):
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="myAuthenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource">
<sec:filter-invocation-definition-source>
<sec:intercept-url pattern="/rest/**" access="ROLE_REST"/>
</sec:filter-invocation-definition-source>
</property>
</bean>
También debería poder asegurar sus servicios REST con anotaciones @Secured
sobre métodos.
El contexto anterior fue extraído de la aplicación de servicio REST existente; disculpe los posibles errores tipográficos.
También es posible hacer al menos la mayor parte de lo que se implementa aquí utilizando etiquetas stock sec
Spring, pero prefiero el enfoque personalizado ya que eso me da el mayor control.
Espero que esto al menos te haga comenzar.
Estamos desarrollando servicios web RESTful con Spring 3 y necesitamos tener la funcionalidad de inicio / cierre de sesión, algo así como /webservices/login/<username>/<password>/
y /webservices/logout
. La sesión debe almacenarse en el contexto hasta que la sesión exceda el tiempo de espera o se cierre la sesión para permitir el consumo de otros servicios web. Cualquier solicitud para acceder a servicios web sin información de sesión debe ser rechazada. Buscando una solución de vanguardia para este escenario.
De hecho, estoy resucitando la pregunta que se hace aquí. Spring Security 3 inicia sesión mediante programación , que todavía no se responde correctamente. Por favor, especifique los cambios necesarios en web.xml también.