0

My Restful service application developed with Spring 3 is deployed on Tomcat7. I use a chrome app called Postman to request REST services.

I have a custom-filter placed before all the services (except the non-secured service login) for checking Session and application specific cookies. This filter returns HTTP status:403 if cookies are not present or invalid in the incoming HttpServletRequest. The filter (myCustomSecurityFilter) is Singleton scoped.

<security:intercept-url pattern="/services/v1/login" access="permitAll()" /> <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myCustomSecurityFilter" />

I observed that in a speicific case old HttpServletRequest is used. Please see the following scenario

Case #1: All requests are over HTTPS.

  1. All cookies are removed and browser is restarted.

  2. Call HTTPS serveice: ..\services\v1\account. As this service has to be called after ..\services\v1\login, 403 response is expected. Actual response :403. A new session is created and a JSESSIONID is returned by Tomcat. Say, JSESSIONID_1.

  3. Request ..\services\v1\login . Expected and Actual respose 200-OK. A new session is created and a JSESSIONID is returned by Tomcat. Say, JSESSIONID_2. Also application specific cookies are returned to client/browser. Say, App_cookie_1.
  4. Call any other service other than ..\services\v1\account. All are successful(200). Cookies JSESSIONID_2, App_cookie_1 are sent by request and the same can be observed after receiveing response. Note: This step is not important. Step 5 can be reproduced with or without this step.
  5. Request ..\services\v1\account. Expected: 200. Actual: 403. When I debugged the HttpServletRequest received by the doFilter method in my SecurityFilter mentioned above, I see that the HttpServletRequest contains old cookies of the previous request to the same service ..\services\v1\account. i.e JSESSIONID_1. No app cookie. I checked cookies with the help of httpServletRequest.getCookies() Browser shows Cookies JSESSIONID_2, App_cookie_1. I am sure that Tomcat receieves Cookies JSESSIONID_2, App_cookie_1 becasue I have access logging enabled. So, it is Spring (my code or config on top of the the Spring framework) passing old HttpServletRequest to filter. But how? why?
  6. Request ..\services\v1\account. Expected: 200. Actual: 200. Cookies JSESSIONID_2, App_cookie_1 are sent by request and the same can be observed after receiveing response. So, old cookies are used only once and that too only for the same service in this case (..\services\v1\account).

Webapp works as expected in the following cases (above steps are denoted by numbers): Case2: 1,2,3,4,5,6. All are HTTPS requests except #2 (login request). #5 returns 200 if #2 is a HTTP request!! This is also a surprise. Case3: 2,3,4,5,6. Case4: 2,3,5,6.

Step 4 is not important. Step 5 can be reproduced with or without this step. I placed this to explain that previous request of the same service is loaded and no effect on other services. Problem is definitely not with ..\services\v1\account. Because I just used this service for example. Case 1 can be repeated with any secured service in the application.

I tried managing my session with newSessio, migrateSession options.

<security:session-management session-fixation-protection="newSession">        
    <security:concurrency-control max-sessions="1" />
</security:session-management>

Thanks for reading my question. It would be great if you could give some pointers. Please let me know if I am not clear.

Techie Rabbit
  • 33
  • 1
  • 5
  • After some more debugging of Spring filter chain. I notice that savedRequest created by HttpSessionRequestCache has old cookies. This Saved session is prepared from the Session attribute SPRING_SECURITY_SAVED_REQUEST of the request. It is just a finding, have not found solution yet :( – Techie Rabbit Feb 09 '15 at 12:44
  • As I couldn't find and solve the Spring frameworks behavior of loading old session form the Session repository I am using following workaround (can be called a preemptive measure) to stop the occurrence of above situation. Preemptive measure : I am routing all 403 responses to my /v1/access-denied service and then INVALIDATING the session in "access-denied". This removes session from the SpringSessionRepository and prevents from loading this session later after authentication. – Techie Rabbit Feb 12 '15 at 11:51

1 Answers1

0

(answering as I faced a similar problem recently. Even though the question is too old)

..\services\v1\login

A new session is created and a JSESSIONID is returned by Tomcat.

How is the session created here?

Assuming its typically created like below

HttpServletRequest.getSession(true);

there is a high chance server gets an old session here. Can you try a

session.Invalidate()

or

 request.logout()

So that any open session is invalidated.after that you try creating the session again

  HttpServletRequest.getSession(true);