Hello,
I am having an odd problem and it took me some time to track it down. I am now able to reproduce it 100% but am not sure what the solution is to the problem.
Background... I have a Spring MVC (3.0.0) project setup using Spring Security (3.0.0). I originally built up the project using Spring Roo (1.0.0). After initial creation through Roo, the applicationContext-security.xml was modified so that a custom login and logout success handler could be used.
The MyAuthenticationHandler class is responsible for creating a custom token cookie that is used within the application. Relevant code from the class is:Code:<http auto-config="true" use-expressions="true"> <form-login login-processing-url="/static/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" authentication-success-handler-ref="myAuthenticationHandler" /> <logout logout-url="/static/j_spring_security_logout" success-handler-ref="logoutHandler" /> ... </http> <beans:bean id="logoutHandler" class="com.myproject.web.LogoutHandler" /> <beans:bean id="myAuthenticationHandler" class="com.myproject.web.MyAuthenticationHandler" />
The LogoutHandler class just deletes the cookie on successful logout.Code:... public class MyAuthenticationHandler implements ServletContextAware, AuthenticationSuccessHandler { ... @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { ... response.addCookie(createCookie(CUSTOM_TOKEN_KEY, encodedToken)); response.sendRedirect(servletContext.getContextPath() + "/logged-in"); } ... }
The last piece of code of importance is the controller that is acting on the main page being displayed.Code:@Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { Cookie token = new Cookie(CUSTOM_TOKEN_KEY, null); token.setMaxAge(0); token.setPath(servletContext.getContextPath()); response.addCookie(token); response.sendRedirect(servletContext.getContextPath()); }
The problem I am running into is that when I debug the Controller, and it breaks on the breakpoint, information showing up in the HttpServletrequest object for the cookie is not correct. Here is an example of how I reproduce the problem:Code:@RequestMapping("/index") @Controller public class MyController { ... @RequestMapping public String get(@CookieValue(value = CUSTOM_TOKEN_KEY, required = false) String customToken, Model model, HttpServletRequest request) { if (customToken != null) // breakpoint is on this line { // process custom token and add data to the model } else { SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false); SecurityContextHolder.clearContext(); } return "index"; } ... }
1. Enter URL for main page.
2. Page redirects to login page. Browser cookie has jsessionid of 721860F1066A12381203EA6F71E63C1A
3. Login successful and redirected to logged-in page. Browser cookie has jsessionid of 1DCE1745DBEAD34281355FFD4E97EB14 and the custom token cookie exists.
4. Click link to main page.
5. Breakpoint on main page controller is hit and HttpServletRequest has cookie for jsessionid as 4CF46F79D2487236A12F9E27EEE1392E but no custom token cookie.
6. Controller logs out player as custom token cookie doesn't exist.
7. Click link to go to main page again (or refresh page).
8. Page redirects to login page. Browser cookie has jsessionid of 1DCE1745DBEAD34281355FFD4E97EB14
9. Login successful and redirected to logged-in page. Browser cookie has jsessionid of B1C80DDCCC5FD4725DA234EDAD91AA0 and the custom token cookie exists.
10. Click link to main page.
11. Breakpoint on main page controller is hit and HttpServletRequest has cookie for jsessionid as 1DCE1745DBEAD34281355FFD4E97EB14 and custom token cookie.
12. Controller adds information to the model, based on information in custom token cookie, and the main page views properly.
13. Click logout link.
14. Redirected to login page. Browser cookie has jsessionid of 8B6FDC7F3A8E657DB44A9C7AB93F8532 and custom token cookie is deleted as part of logout process.
15. Login successful and redirected to logged-in page. Browser cookie has jsessionid of 2920EA0E139EACA83AB20F248480D6E1. Custom token cookie exists.
16. Click link to go to main page.
17. Main page controller has request cookie for jsessionid as B1C80DDCCC5FD4725DA234EDAD91AA0B but no custom token cookie.
At this point I can continue to loop through the testing by repeating steps 6 to 17. Each time the jsessionid's will have the same consistency and the custom token cookie will exist / not exist in the same spots. What I expected to happen on the same steps is:
1. Enter URL for main page.
2. Page redirects to login page. Browser cookie has jsessionid of <RandomJSessionID111>
3. Login successful and redirected to logged-in page. Browser cookie has jsessionid of <RandomJSessionID222> and the custom token cookie exists.
4. Click link to main page.
5. Breakpoint on main page controller is hit and HttpServletRequest has cookie for jsessionid as <RandomJSessionID222> and custom token cookie.
6. Controller adds information to the model, based on information in custom token cookie, and the main page views properly.
I am not sure how the Spring MVC is returning request cookies for requests other than the current request. I have confirmed that the browser is sending the proper cookies along with the request to each page. The only thing I can think is causing problems is I am not doing something correct in my login success handler and as such the request isn't being consumed properly and is still available for the next controller to pickup. It feels like the server is one request behind which is a little scary as that would lead to data polution between sessions.
I have posted this in the Spring Security forum as I think the problem is related to my handlers but it may be a Spring MVC issue. If so please let me know so I can post it there as well.
Thanks


