1

As I am moving from Spring 3.1.1.RELEASE to 4.0.2 RELEASE I have had to make some changes to spring security context.

Almost everything is ok except POST Request for logout.

I could make entire line to be form method="POST" action="logout" but then I have to deal with Submit which is totally different styling then what we need. I have tried sending logout request with csrf data over ajax with no success. Any help is greatly appreciated. P.S. Disabling csrf is not an option.

 <!-- JSP -->
 <meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>

<!--Anchor -->
<a id="loggg" href="logout">Logout1</a>

<!-- jquery -->
$("#loggg").click(function(e){
    e.preventDefault();
     var token = $("meta[name='_csrf']").attr("content");
      var header = $("meta[name='_csrf_header']").attr("content");
    $.ajax({
        url : "logout",
        method : "POST",
        data :token ,
        success : function(data) { 
            console.log("clicked");
        }, 
        error : function(data) {
            console.log(data);
        }
    });

})

FireBug developer console returns :

403 Forbidden 2ms
"NetworkError: 403 Forbidden - http://localhost:8081/nekretnine/logout"
Object { readyState=4,  responseText="<!DOCTYPE html><html> 
<he...EASE</h3></body></html>",  status=403,  more...}
SeaBiscuit
  • 2,553
  • 4
  • 25
  • 40

2 Answers2

1

If your login is an AJAX request from the same page, that would have changed the token in the server. Spring Security changes the token in events like login and logout.

So, your token in the page would no more be valid.

If this turns out to be the case, one way would be to fetch the new token using a GET request after having a filter attaching the token as a cookie, as explained here.

This also might be helpful.

Community
  • 1
  • 1
Sanjay
  • 8,755
  • 7
  • 46
  • 62
  • Thank you for your reply. I am almost certain the problem is in ajax post request. I did a small test with regular form and button instead anchor and it is working perfectly. Any thoughts?
    – SeaBiscuit Aug 23 '15 at 14:10
  • Quick guess: the `data: token` in the AJAX request seems ok? Shouldn't the token be posted either as a form parameter, in the format `_csrf:token-val` or as a header in similar format? – Sanjay Aug 24 '15 at 03:34
1

I have managed to partially solve this issue. This answer is for those who might stumble on to the same problem as i did when i moved from Spring Security 3.1.1 to Spring security 4.0.2

JSP

 <meta name="_csrf" content="${_csrf.token}"/>
 <!-- default header name is X-CSRF-TOKEN -->
 <meta name="_csrf_header" content="${_csrf.headerName}"/>

Anchor

<a id="loggg" href="logout">Logout1</a>

Jquery

$("#loggg").click(function(e){
    e.preventDefault();
     var token = $("meta[name='_csrf']").attr("content");
      var header = $("meta[name='_csrf_header']").attr("content");
    $.ajax({
        url : 'logout',
        type : 'POST',
        data: token,
        beforeSend:function(xhr){
             xhr.setRequestHeader(header, token);
        },
        success : function(data) { 
            window.location ="/home";    here is the only problem, for some reason after logging out page doesnt refresh and i can still see myself logged in. Then i usually just press f5 and i am logged out.
        }, 
        error : function(data) {
            console.log(data);
        }
    });

})

Few problems i noticed when i changed from Spring security 3 to Spring Security 4. Here are some :

Attributes are no longer j.username i j.password instead use- username password

  1. Action is no longer j_spring_security_check ,instead use - login
  2. Logout action is no longer j_spring_security_logout use logout
  3. Request must be post, even for logout.
  4. U need to add CSRF token

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

to forms, or if u use spring forms, csrf.token will be added automatically. Also u can use

u need to add these filters ( u must add them before Spring security filter)

<filter>
        <display-name>springMultipartFilter</display-name>
             <filter-name>springMultipartFilter</filter-name>
        <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
    </filter>
    <filter-mapping>
             <filter-name>springMultipartFilter</filter-name>
             <url-pattern>/*</url-pattern>
    </filter-mapping>
  1. You were probably using multipartResolver resolver bean, which you will need to change to <beans:bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <beans:property name="maxUploadSize" value="-1" />

  2. Also if you have done all this and you still cant upload files using commons-fileUpload you (as myself) probably placed filterMultyPartResolver in servlet-context , which was working just fine in previous version, now with no compile errors you will just end up in a dead-end street not knowing what to do. Solution is very simple, just move bean to root-context.xml and voala! all is working perfectly.

SeaBiscuit
  • 2,553
  • 4
  • 25
  • 40