java.lang.IllegalStateException:getAttributeNames:会话已在 Spring 安全 HttpSessionDestroyedEvent 中失效

java.lang.IllegalStateException: getAttributeNames: Session already invalidated in Spring security HttpSessionDestroyedEvent

当我尝试处理 SessionDestroyEvent:

时发生此异常
public class SessionEndedListener implements ApplicationListener<SessionDestroyedEvent> {
    private final ContractorService contractorService;

    @Autowired
    public SessionEndedListener(ContractorService contractorService) {
        this.contractorService = contractorService;
    }

    @Override
    public void onApplicationEvent(SessionDestroyedEvent sessionDestroyedEvent) {
        sessionDestroyedEvent.getSecurityContexts()
    }
}

它发生是因为在 SessionDestroyedEvent 会话已经失效。 但在 HttpSessionEventPublisher 会话有效。

java.lang.IllegalStateException: getAttributeNames: Session already invalidated
    at org.apache.catalina.session.StandardSession.getAttributeNames(StandardSession.java:1199)
    at org.apache.catalina.session.StandardSessionFacade.getAttributeNames(StandardSessionFacade.java:120)
    at org.springframework.security.web.session.HttpSessionDestroyedEvent.getSecurityContexts(HttpSessionDestroyedEvent.java:51)
    at com.ordotrans.util.listener.SessionEndedListener.onApplicationEvent(SessionEndedListener.java:29)
    at com.ordotrans.util.listener.SessionEndedListener.onApplicationEvent(SessionEndedListener.java:18)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:159)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.run(SimpleApplicationEventMulticaster.java:134)
    at java.lang.Thread.run(Thread.java:745)

我找到了解决办法,但它看起来像拐杖。

@WebListener
public class SessionCounterListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        session.setMaxInactiveInterval(60*15);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

        HttpSession session = httpSessionEvent.getSession();
        SessionDestroyedEvent sessionDestroyedEvent = new HttpSessionDestroyedEvent(session);
        ApplicationContext ctx =
                WebApplicationContextUtils.
                        getWebApplicationContext(session.getServletContext());
        ContractorService contractorService = (ContractorService) ctx.getBean("contractorService");
        for (SecurityContext securityContext : sessionDestroyedEvent.getSecurityContexts()) {
            Authentication authentication = securityContext.getAuthentication();
            CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();

        }

    }

}