Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring prevent ajax call from being target url on authentication

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?

like image 286
jlars62 Avatar asked Sep 26 '22 21:09

jlars62


2 Answers

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>
like image 188
Rob Winch Avatar answered Oct 11 '22 10:10

Rob Winch


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.

like image 45
jlars62 Avatar answered Oct 11 '22 12:10

jlars62