Весенний запуск SamlLogoutHandler из HttpSessionListener - PullRequest
0 голосов
/ 30 октября 2018

Мне нужно аннулировать мой сеанс SAML (okta), пока истекает мой HttpSession. Для этой цели я создал HttpSessionListener, и его метод уничтожения успешно выполняется при уничтожении сеанса, поэтому я могу подключить туда свой код:

@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 из Listener? Или я могу сделать это как-то проще?

...