Reputation: 15
I use this code. After setting passwordChanged
, when I click (first request) then it invalidates the session in authenticationServices.logout(getHttpServletRequest())
, and on the next request it goes to the login page (I have to double click to go to the login page). I want to go to login page when I click request for the first time after session invalidates.
public class LogOutAfterChangePasswordInterceptor extends BaseInterceptor {
private static final long serialVersionUID = 5906534052815899264L;
private static final Logger LOG =
LoggerFactory.getLogger(LogOutAfterChangePasswordInterceptor.class);
private static final String ACTIONS_TO_REMEMBER = "static-password-setting-result";
private static final String PASSWORD_CHANGED_FLAG = "passwordChanged";
public static final String LOGIN = "login";
@Inject
private AuthenticationServices authenticationServices;
@Override
public String intercept (ActionInvocation invocation) throws Exception {
invocation.addPreResultListener((actionInvocation, resultCode) -> {
HttpServletRequest request = getHttpServletRequest();
HttpSession session = request.getSession(false);
if (getActionName().contains(ACTIONS_TO_REMEMBER)) {
LOG.trace("push URL `{}` that user after that should be logout ",
ACTIONS_TO_REMEMBER);
session.setAttribute(PASSWORD_CHANGED_FLAG, true);
} else {
Boolean passwordChanged = session != null ? (Boolean)
session.getAttribute(PASSWORD_CHANGED_FLAG) : null;
if (passwordChanged != null && passwordChanged) {
// Perform logout or other necessary actions
session.removeAttribute(PASSWORD_CHANGED_FLAG);
LOG.trace("User will be logged out after the next request");
try {
authenticationServices.logout(getHttpServletRequest());
} catch (ClientException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// logout spring manually
Authentication auth =
SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
new
SecurityContextLogoutHandler().logout(getHttpServletRequest(),
getHttpServletResponse(),auth);
}
SecurityContextHolder.getContext().setAuthentication(null);
}
}
});
return invocation.invoke();
}
}
Upvotes: 0
Views: 55
Reputation: 1
You have misunderstood how the HTTP session works. You code will work only if the current session is valid (However, you have to remove a preresult listener wrapped around a code). When the session expires or you invalidate a session when you did logout from the browser, the interceptor won't work as expected, because you didn't check a session for validity at the first.
You should change your code and add a check for validity of the session when you trying to get a current session. The validity of the session is provided by the servlet API when you call request.getSesdion(false)
. You can learn about it more if you read java httpsession is valid? question.
Hence, you should check a session variable at first and if it is not available, return to the LOGIN
result.
@Override
public String intercept (ActionInvocation invocation) throws Exception
HttpServletRequest request = getHttpServletRequest();
HttpSession session = request.getSession(false);
if (session == null)
return LOGIN;
...
Upvotes: 0