只要我的HttpSession过期,我就需要使SAML(okta)会话无效。为此,我创建了HttpSessionListener,并且其destroy方法在会话destroy上成功执行,因此可以在此处插入我的代码:
@Bean
public HttpSessionListener httpSessionListener() {
return new HttpSessionListener() {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("Session Created with session id+" + se.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("Session Destroyed, Session id:" + se.getSession().getId());
}
};
}
我发现Spring允许使用其自己的类使SAML会话无效,因此我将一些代码复制到新类中,如下所示:
public class SamlLogoutHandler extends SimpleUrlLogoutSuccessHandler {
private static final String LOGOUT_PARAMETER = "local";
private SingleLogoutProfile profile;
private SAMLContextProvider contextProvider;
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
try {
if (authentication != null && isGlobalLogout(request, authentication)) {
Assert.isInstanceOf(SAMLCredential.class, authentication.getCredentials(),
"Authentication object doesn't contain SAML credential, cannot perform global logout");
// Terminate the session first
HttpSession session = request.getSession(false);
SecurityContextHolder.clearContext();
if (session != null) {
session.invalidate();
}
// Notify session participants using SAML Single Logout profile
SAMLCredential credential = (SAMLCredential) authentication.getCredentials();
request.setAttribute(SAMLConstants.LOCAL_ENTITY_ID, credential.getLocalEntityID());
request.setAttribute(SAMLConstants.PEER_ENTITY_ID, credential.getRemoteEntityID());
SAMLMessageContext context = contextProvider.getLocalAndPeerEntity(request, response);
profile.sendLogoutRequest(context, credential);
}
} catch (SAMLException e) {
logger.debug("Error initializing global logout", e);
throw new ServletException("Error initializing global logout", e);
} catch (MetadataProviderException e) {
logger.debug("Error processing metadata", e);
throw new ServletException("Error processing metadata", e);
} catch (MessageEncodingException e) {
logger.debug("Error encoding outgoing message", e);
throw new ServletException("Error encoding outgoing message", e);
}
super.onLogoutSuccess(request, response, authentication);
}
private boolean isGlobalLogout(HttpServletRequest request, Authentication auth) {
String localLogout = request.getParameter(LOGOUT_PARAMETER);
return (localLogout == null || !"true".equals(localLogout.toLowerCase().trim()))
&& (auth.getCredentials() instanceof SAMLCredential);
}
public void setProfile(SingleLogoutProfile profile) {
this.profile = profile;
}
public void setContextProvider(SAMLContextProvider contextProvider) {
this.contextProvider = contextProvider;
}
}
问题是:如何从侦听器运行onLogoutSuccess方法?还是我可以更轻松地做到这一点?