5

I have a working Spring/Java web application. On some pages, when I log out, the last request to be made is an AJAX call. So, when I log back in, Spring redirects me to the ajax call giving me a browser full of json. My login success handler extends the SavedRequestAwareAuthenticationSuccessHandler.

How can I control which url's get forwarded to on a successful login?

jlars62
  • 7,183
  • 7
  • 39
  • 60

2 Answers2

3

The best approach is to prevent the request from being cached in the first place. If you use Spring Security's Java Configuration it automatically ignores any request with "X-Requested-With: XMLHttpRequest" set.

You can also specify your own HttpSessionRequestCache with a RequestMatcher on it that specifies when a request should be saved. For example, you could use the following XML configuration to ignore any JSON requests:

<b:bean id="requestCache" 
        class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
  <b:property name="requestMatcher">
    <b:bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
      <b:constructor-arg>
        <b:bean class="org.springframework.security.web.util.matcher.MediaTypeRequestMatcher">
          <b:constructor-arg>
            <b:bean class="org.springframework.web.accept.HeaderContentNegotiationStrategy"/>
          </b:constructor-arg>
          <b:constructor-arg value="#{T(org.springframework.http.MediaType).APPLICATION_JSON}"/>
        </b:bean>
      </b:constructor-arg>
      <b:property name="useEquals" value="true"/>
    </b:bean>
  </b:property>
</b:bean>

<http ...>
    <!-- ... -->
    <request-cache ref="requestCache"/>
</http>
Rob Winch
  • 21,440
  • 2
  • 59
  • 76
  • I finally got back to fixing this issue. Thanks for your answer! – jlars62 Nov 18 '16 at 22:56
  • 1
    This worked for me, thank you! One small typo in your answer, the `useEquals` property is in the `MediaTypeRequestMatcher` instead of `NegatedRequestMatcher`. – Darren Parker Mar 23 '18 at 16:59
1

My solution is inspired by Rob Winch's answer. Though, in my scenario, Spring was saving requests that had X-Requested-With: XMLHttpRequest set. These were the requests I had to ignore.

I created a class to be my custom RequestCache class.

@Service("customRequestCache")
public class CustomRequestCache extends HttpSessionRequestCache { //this class (bean) is used by spring security

    @Override
    public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
        if (!"XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"))) {
            //request is not ajax, we can store it
            super.saveRequest(request, response);
        } else {
            //do nothing, add some logs if you want
        }
    }
}

Then, in my spring security config:

<http>
    <request-cache ref="customRequestCache" />
</http>

With this custom request cache class being used, ajax requests are no longer being stored.

jlars62
  • 7,183
  • 7
  • 39
  • 60