How to implement login page using Spring Security so that it works with Spring web flow?

simon picture simon · May 21, 2010 · Viewed 19.4k times · Source

I have a web application using Spring 2.5.6 and Spring Security 2.0.4. I have implemented a working login page, which authenticates the user against a web service. The authentication is done by defining a custom authentincation manager, like this:


<beans:bean id="customizedFormLoginFilter"
    class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
    <custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />
    <beans:property name="defaultTargetUrl" value="/index.do" />
    <beans:property name="authenticationFailureUrl" value="/login.do?error=true" />
    <beans:property name="authenticationManager" ref="customAuthenticationManager" />
    <beans:property name="allowSessionCreation" value="true" />
</beans:bean>

<beans:bean id="customAuthenticationManager"
    class="com.sevenp.mobile.samplemgmt.web.security.CustomAuthenticationManager">
    <beans:property name="authenticateUrlWs" value="${WS_ENDPOINT_ADDRESS}" />
</beans:bean>

The authentication manager class:


public class CustomAuthenticationManager implements AuthenticationManager, ApplicationContextAware {

    @Transactional
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

                //authentication logic

        return new UsernamePasswordAuthenticationToken(principal, authentication.getCredentials(),
                grantedAuthorityArray);
    }

The essential part of the login jsp looks like this:


<c:url value="/j_spring_security_check" var="formUrlSecurityCheck"/>
<form method="post" action="${formUrlSecurityCheck}">
    <div id="errorArea" class="errorBox"> 
       <c:if test="${not empty param.error}">
          ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
      </c:if>
  </div>
    <label for="loginName">
        Username:           
        <input style="width:125px;" tabindex="1" id="login" name="j_username" />
    </label>

    <label for="password">
        Password:           
        <input style="width:125px;" tabindex="2" id="password" name="j_password" type="password" />
    </label>
    <input type="submit" tabindex="3" name="login" class="formButton" value="Login" />
</form>

Now the problem is that the application should use Spring Web Flow. After the application was configured to use Spring Web Flow, the login does not work anymore - the form action to "/j_spring_security_check" results in a blank page without error message. What is the best way to adapt the existing login process so that it works with Spring Web Flow?

Edit: there was no error message, just a blank page was displayed. It works now - the problem was that web.xml was missing entries


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

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Since I cannot cancel the bounty although the problem is solved, the bounty is awarded to most insightful answer or link, which would help other people in configuring Spring Security and Web Flow to work together.

Answer

mdma picture mdma · May 30, 2010

Here's documentation describing why the 'springSecurityFilterChain' is needed.

The springSecurityFilterChain filter is not created explicitly, but created implicitly by the <http> spring security schema element in the application context

<http auto-config="false" session-fixation-protection="none">
    <form-login login-page="/login.jsp" default-target-url="/home.htm" />
</http>

The beans created require an authentication provider, so we provide one

<authentication-provider>
   <user-service id="userDetailsService">
      <user password="password" name="username" authorities="ROLE_USER" />
   </user-service>
</authentication-provider

With these changes in place, including configuration of the security filter as described in the edited question, the page will render correctly and the configured security stack will be in place on each page served.

These details and a walk-through a simple spring-security application is given in A aimple web application with Spring Security - part 13.

The reference documentation describes setting up the springSecurityFilterChain as the first part of configuring web.xml: Security Namespace Configuration - Getting Started. (Linked to 2.0.x version used by the OP. The latest version 3.1 is here.)