franbisc
franbisc

Reputation: 59

Spring Security: how to add a filtering control before another module's security call

I have a J2EE application with security authorization implementation, which, as a first step, calls a dependency for the security authorization operations. In this dependency module it's been checked if the access token is null: if so it throws a NullPointerException. I need to catch this exception in my application in order to redirect to a jsp custom page instead of a 500 error page.

The point is that I never pass through one of my app classes, so I can't catch the exception because is not my application that directly calls the other: the chain is handled by Spring Security mechanism. From the stack trace I see that I pass on DelegatingFilterProxy, then on FilterChainProxy, on SecurityContextPersistenceFilter, on LogoutFilter and at this point the control passes on the dependency application, where the Exception is thrown.

Is there a way I can add a preventive control on the token string so I control the redirect before calling the dependency for security?

This is the Spring configuration that permits Spring to call the dependency filter(preAuthenticationFilter) as a first step:

<http auto-config="true" access-denied-page="/500" use-expressions="true">
    <custom-filter position="PRE_AUTH_FILTER" ref="preAuthenticationFilter" />
    <intercept-url pattern="/portal/**" access="isAuthenticated()" />
    <intercept-url pattern="/**" access="permitAll" />

    <logout logout-url="/logout" delete-cookies="true"
        invalidate-session="true" logout-success-url="/logoutsuccess" />

    <session-management session-fixation-protection="newSession" />
</http>

Edit: here is the modify to the bean configuration to define the FilterWrapper:

<bean id="preAuthenticationFilter" class="com.example.FilterWrapper">
    <constructor-arg>
        <bean class="com.example.MyPreAuthenticationFilter" >
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="continueFilterChainOnUnsuccessfulAuthentication" value="false" />
            <property name="verifyTokenChanged" value="true" />
        </bean>
    </constructor-arg>
</beans:bean>

Upvotes: 0

Views: 640

Answers (1)

marthursson
marthursson

Reputation: 3300

The custom filter should obviously be fixed so that it doesn't throw NullPointerException. From your post I realise that the code for this filter is probably not under your control, but it appears it is initialised in your Spring context, which means you can always create a wrapper for it where you catch the exception, i.e. something like:

public class FilterWrapper extends OncePerRequestFilter {
  private final Filter target;

  public FilterWrapper(Filter target) {
     this.target = target;
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    try {
      target.doFilter(request, response, filterChain);
    } catch(NullPointerException e) {
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication token is required");
    }
  }
}

Now, change the bean definition for the preAuthenticationFilter to use your wrapper around the original filter and you should be fine.

Somewhere in your configuration file there should be a bean definition like this:

<bean class="com.example.MyPreAuthenticationFilter" id="preAuthenticationFilter" />

Change that definition to:

<bean class="com.example.FilterWrapper" id="preAuthenticationFilter">
  <constructor-arg>
    <bean class="com.example.MyPreAuthenticationFilter" />
  </constructor-arg>
</bean>

Upvotes: 1

Related Questions