2010-09-30 15 views
8

Quiero omitir el formulario de inicio de sesión para Spring webflow (Spring 2.0.5) en ciertos escenarios (por lo que el formulario de inicio de sesión se presenta para usuarios normales pero cuando el URL es http://server.com/myspringapp/fakelogin?username=FakeUser&password=FakePassword) no se debe presentar el formulario de inicio de sesión, sino que se debe autenticar internamente según los parámetros de solicitud y luego llevarlo a la página segura).Spring Security: Omitir formulario de inicio de sesión

Así que no quiero Preauthenticastion, sino una autenticación transparente en ocasiones especiales (cuando la URL es como se mencionó anteriormente). Vi hilos como http://forum.springsource.org/showthread.php?t=59108 pero no se menciona una solución. Intenté implementar AuthenticationProcessingFilter pero no estoy muy seguro de cómo implementar el método requiresAuthentication().

que sigue es mi actual XML seguridad:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
         http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"> 

    <bean id="customAuthenticationProvider" class="com.myco.jsf.spring.security.MyAuthenticationProvider"> 
     <security:custom-authentication-provider/> 
     <constructor-arg> 
      <ref bean="webSessionFactory"/> 
     </constructor-arg> 
     <constructor-arg> 
      <ref bean="authenticationBridge"/> 
     </constructor-arg> 
    </bean> 

    <bean id="myEntryPoint" class="com.myco.web.filter.CustomAuthenticationEntryPoint"> 
     <property name="loginFormUrl" value="/spring/login" /> 
    </bean> 

    <bean id="myProcessingFilter" class="com.myco.web.filter.CustomAuthenticationProcessingFilter"> 
     <security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER" /> 
     <property name="defaultTargetUrl" value="/spring/secure" /> 
     <property name="authenticationFailureUrl" value="/spring/login" /> 
     <property name="alwaysUseDefaultTargetUrl" value="false" /> 
     <property name="filterProcessesUrl" value="/spring/j_spring_security_check" />  
     <property name="authenticationManager" ref="authenticationManager" />    
     <!--    
     <property name="allowSessionCreation" value="true" />     
     --> 
    </bean>  

    <security:authentication-manager alias="authenticationManager"/> 

     <security:http auto-config="false" access-denied-page="/spring/notpermitted" entry-point-ref="myEntryPoint">  
     <security:anonymous/> 
     <!--  
     <security:form-login login-page="/spring/login" login-processing-url="/spring/j_spring_security_check" default-target-url="/spring/secure" 
      always-use-default-target="false" authentication-failure-url="/spring/login" /> 
     --> 
     <security:logout logout-url="/spring/j_spring_security_logout" logout-success-url="/spring/pages/logout" /> 
     </security:http> 

</beans> 

que sigue es mi clase de filtro:

public class CustomAuthenticationProcessingFilter extends 
     AuthenticationProcessingFilter { 

    @Override 
    protected void successfulAuthentication(HttpServletRequest request, 
      HttpServletResponse response, Authentication authResult) 
      throws IOException, ServletException { 
     super.successfulAuthentication(request, response, authResult); 

     System.out.println("==successful login=="); 
    } 

    @Override 
    protected void unsuccessfulAuthentication(HttpServletRequest request, 
      HttpServletResponse response, AuthenticationException failed) 
      throws IOException, ServletException { 
     super.unsuccessfulAuthentication(request, response, failed); 

     System.out.println("==failed login=="); 
    } 

    @Override 
    protected boolean requiresAuthentication(HttpServletRequest request, 
      HttpServletResponse response) { 
     boolean retVal = false; 
     String username = request.getParameter("j_username"); 
     String password = request.getParameter("j_password"); 

     if (username != null && password != null) { 
      Authentication authResult = null; 
      try { 
       authResult = attemptAuthentication(request);     
       if (authResult == null) { 
        retVal = false; 
       } 

      } catch (AuthenticationException failed) { 
       try { 
        unsuccessfulAuthentication(request, response, failed); 
       } catch (Exception e) { 
        retVal = false; 
       } 
       retVal = false; 
      } 

      try { 
       successfulAuthentication(request, response, authResult); 
      } catch (Exception e) { 
       retVal = false; 
      } 

      return false; 
     } else { 
      retVal = super.requiresAuthentication(request, response); 
     } 
     return retVal; 
    } 

} 

soy capaz de autenticar usando los parámetros de la petición suministrados y el objeto de autenticación se ha creado correctamente. Una vez que el filtro avanza, obtengo la excepción:

15:29:08,734 INFO [STDOUT] 53453 ERROR [http-127.0.0.1-8080-2]  org.ajax4jsf.webapp.BaseXMLFilter  - Exception in the filter chain 
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:659) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206) 
    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290) 
    at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388) 
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at com.myco.jsf.filter.CharsetFilter.doFilter(CharsetFilter.java:38) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) 
    at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
    at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:278) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235) 
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
    at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:173) 
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182) 
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) 
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) 
    at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:393) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) 
    at java.lang.Thread.run(Thread.java:619) 
Caused by: java.lang.IllegalStateException 
    at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407) 
    at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:108) 
    at org.springframework.security.context.HttpSessionContextIntegrationFilter$OnRedirectUpdateSessionResponseWrapper.sendError(HttpSessionContextIntegrationFilter.java:498) 
    at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:108) 
    at org.ajax4jsf.webapp.FilterServletResponseWrapper.sendError(FilterServletResponseWrapper.java:655) 
    at com.sun.facelets.FaceletViewHandler.handleFaceletNotFound(FaceletViewHandler.java:711) 
    at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:658) 
    at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100) 
    at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176) 
    at org.springframework.faces.mvc.JsfView.renderMergedOutputModel(JsfView.java:83) 
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250) 
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647) 
    ... 61 more 

¿Me pueden ayudar con el motivo por el que aparece este error? ¿Estoy usando el tipo correcto de filtro personalizado? Aprecio tu ayuda.

Respuesta

6

Hice algo similar con Spring Security 3 y creo que debería ser posible con versiones anteriores también. Modifiqué mi código, por lo que se adapta a tu situación. Es posible que deba resolver algunos de los detalles, pero debe proporcionarle la idea básica.

se puede manejar usando un filtro:

public class MyAuthenticationFilter extends DelegatingFilterProxy 
{ 
    public void doFilter ... 
    { 
      String username = request.getParameter("username"); 
      String password = request.getParameter("password"); 

      // build authentication token for user 
      final Authentication auth = new UsernamePasswordAuthenticationToken(...); 
      auth.setAuthenticated(true); 

      // set authentication in context 
      SecurityContextHolder.getContext().setAuthentication(auth); 
    } 

En su web.xml:

<filter> 
    <filter-name>myAuthenticationFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>myAuthenticationFilter</filter-name> 
    <url-pattern>/fakelogin*</url-pattern> 
</filter-mapping> 

En su spring.xml:

<bean id="myAuthenticationFilter" class=... /> 

Otra opción sería la de permitir a todos los usuarios acceder a fakeLogin

<intercept-url pattern="/fakelogin/**" access="permitAll" /> 

y coloque la Autenticación en el contexto de seguridad en una Acción de flujo web.

+1

También puede consultar el filtro de preautenticación de Spring. – martin

Cuestiones relacionadas