Обход списков и потоков с функцией, возвращающей будущее

Я столкнулся с подобной проблемой и применил фильтр в цепочке фильтров для обнаружения запросов AJAX и ответа с настроенным статусом HTTP (вы можете изменить его на 401, если хотите).

В принципе, есть три части. Во-первых, это фильтр. Это фильтр сервлетов и проверяет запрос, а также состояние аутентификации в сеансе. Во-вторых, определение фильтра как компонента в контексте приложения в Resources.groovy. Наконец, вставив его в цепочку фильтров Spring Security, которую я сделал в Bootstrap.groovy.

Я проведу вас через это.

Сначала фильтр сервлета (в src / java)

package com.xyz.security;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.util.ThrowableAnalyzer;
import org.springframework.security.web.util.ThrowableCauseExtractor;
import org.springframework.web.filter.GenericFilterBean;

public class AjaxTimeoutRedirectFilter extends GenericFilterBean {

    // private static final Logger logger =
    // LoggerFactory.getLogger(AjaxTimeoutRedirectFilter.class);

    private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
    private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();

    private int customSessionExpiredErrorCode = 901;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(request, response);

            // logger.debug("Chain processed normally");
        } catch (IOException ex) {
            throw ex;
        } catch (Exception ex) {
            Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex);
            RuntimeException ase = (AuthenticationException) throwableAnalyzer
                    .getFirstThrowableOfType(AuthenticationException.class,
                            causeChain);

            if (ase == null) {
                ase = (AccessDeniedException) throwableAnalyzer
                        .getFirstThrowableOfType(AccessDeniedException.class,
                                causeChain);
            }

            if (ase != null) {
                if (ase instanceof AuthenticationException) {
                    throw ase;
                } else if (ase instanceof AccessDeniedException) {

                    if (authenticationTrustResolver
                            .isAnonymous(SecurityContextHolder.getContext()
                                    .getAuthentication())) {
                        // logger.info("User session expired or not logged in yet");
                        String ajaxHeader = ((HttpServletRequest) request)
                                .getHeader("X-Requested-With");

                        if ("XMLHttpRequest".equals(ajaxHeader)) {
                            // logger.info("Ajax call detected, send {} error code",
                            // this.customSessionExpiredErrorCode);
                            HttpServletResponse resp = (HttpServletResponse) response;
                            resp.sendError(this.customSessionExpiredErrorCode);
                        } else {
                            // logger.info("Redirect to login page");
                            throw ase;
                        }
                    } else {
                        throw ase;
                    }
                }
            }

        }
    }

    private static final class DefaultThrowableAnalyzer extends
            ThrowableAnalyzer {
        /**
         * @see org.springframework.security.web.util.ThrowableAnalyzer#initExtractorMap()
         */
        protected void initExtractorMap() {
            super.initExtractorMap();

            registerExtractor(ServletException.class,
                    new ThrowableCauseExtractor() {
                        public Throwable extractCause(Throwable throwable) {
                            ThrowableAnalyzer.verifyThrowableHierarchy(
                                    throwable, ServletException.class);
                            return ((ServletException) throwable)
                                    .getRootCause();
                        }
                    });
        }

    }

    public void setCustomSessionExpiredErrorCode(
            int customSessionExpiredErrorCode) {
        this.customSessionExpiredErrorCode = customSessionExpiredErrorCode;
    }
}

Во-вторых, определение фильтра как компонента в контексте приложения в Resources.groovy

beans = {
    ajaxTimeoutRedirectFilter(com.xyz.security.AjaxTimeoutRedirectFilter)
}

И, наконец, получение фильтра в Spring Security (я использовал BootStrap.groovy для этого)

import grails.plugin.springsecurity.SecurityFilterPosition
import grails.plugin.springsecurity.SpringSecurityUtils
class BootStrap {

    def init = { servletContext ->

        SpringSecurityUtils.clientRegisterFilter('ajaxTimeoutRedirectFilter', SecurityFilterPosition.EXCEPTION_TRANSLATION_FILTER.order + 10)

    }
    def destroy = {
    }
}
30
задан Community 23 May 2017 в 11:46
поделиться