方案1
package jp.co.toppan.dch.web.core.security;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class CustomInvalidSessionStrategy implements InvalidSessionStrategy {
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Cookie cookie = new Cookie("JSESSIONID", null);
cookie.setPath(getCookiePath(request));
cookie.setMaxAge(0);
response.addCookie(cookie);
String xRequestedWith = request.getHeader("x-requested-with");
// ajax
if (StringUtils.isNotBlank(xRequestedWith) && "XMLHttpRequest".equals(xRequestedWith)) {
response.setStatus(408);
}else {
String servletPath = request.getServletPath();
logout后直接跳到login画面,其他情况跳到timeout画面
if (StringUtils.isNotBlank(servletPath) && "/index".equals(servletPath)) {
request.getRequestDispatcher(servletPath).forward(request,response);
}else{
request.getRequestDispatcher("/408").forward(request,response);
}
}
}
private String getCookiePath(HttpServletRequest request) {
String contextPath = request.getContextPath();
return contextPath.length() > 0 ? contextPath : "/";
}
}
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
.requestMatchers("/index", "/Login", "/408", "/favicon.ico", "/temp/", "/assets/", "/plugins/**")
.permitAll()
.anyRequest().authenticated())
.sessionManagement(session -> session.invalidSessionStrategy(customInvalidSessionStrategy))
.logout(logout->logout.deleteCookies("JSESSIONID"));
}
}
@Controller
public class ErrorController extends BaseController {
@GetMapping("/408")
public String error408() {
return "error/408";
}
}
前台ajax处理
$.ajaxSetup({
...
error: function (data) {
if (data.status == 408) {
window.location = "...";
}
}
});
方案2
核心是配置
http.sessionManagement(session -> session
.invalidSessionUrl("/timeout");
controller文件
@GetMapping("/timeout")
public String timeout(HttpServletRequest request, HttpServletResponse response) {
String xRequestedWith = request.getHeader("x-requested-with");
if ("XMLHttpRequest".equals(xRequestedWith)) {
response.setStatus(408);
return null;
}else{
return "error/408";
}
}
参考地址:
https://docs.spring.io/spring-security/reference/servlet/authentication/session-management.html