Может ли фильтр (в веб-приложении Spring Boot) проверять URL-адрес запроса на основе всех определенных RequestMapping? - PullRequest
0 голосов
/ 22 сентября 2018

Есть ли способ проверить в сервлет-фильтре, является ли URL-адрес запроса действительным (на основе всех отображений запросов, определенных для всех контроллеров в приложении?

Я реализовал фильтр вВеб-приложение Spring Boot (украшено @Component и @Order(Ordered.HIGHEST_PRECEDENCE). Фильтр отвечает за выполнение некоторых проверок полученного сертификата клиента и, если все выглядит хорошо, он передает запрос дальше по цепочке, чтобы в конечном итоге его забрал контроллер.

Но я хочу проверить URL-адрес перед выполнением любых других проверок, таких как проверка сертификата, поэтому я могу сразу указать, является ли это 404. Потому что я столкнулся с ситуацией, когда это стало необходимым.

Обновлено 9/23/2018

AuthFilter.java

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthFilter implements Filter {

    private final Logger logger = LoggerFactory.getLogger(AuthFilter.class);

    // Define paths that require only client certificate but no Authorization token
    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(
            new HashSet<>(
                    Arrays.asList("/login", "/register", "/error" )));

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.debug("Initiating AuthFilter...");
    }

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

        if (!(request instanceof HttpServletRequest)) {
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String path = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()).replaceAll("[/]+$", StringUtils.EMPTY);
        logger.debug("AuthFilter intercepting request: {}", path);
        boolean allowedPath = ALLOWED_PATHS.contains(path);

        int responseCode = 400;
        String responseException = null;

        if (allowedPath) {

            if (this.checkClientCert(CLIENT_CERT_NAME, httpRequest)) {
                logger.debug("{} cert is valid, moving request along", CLIENT_CERT_NAME);
                chain.doFilter(request, response);
                return;
            }

            responseCode = 403;
            responseException = new AuthException("certificate missing", "Must provide a valid client certificate");
            sendResponse(responseCode, responseException, httpResponse);
            return;
        }

        try {

            logger.debug("Checking {} cert and authorization token...", CLIENT_CERT_NAME);
            boolean validClientCert = this.checkClientCert(CLIENT_CERT_NAME, httpRequest);
            boolean validAuthToken = this.checkAuthToken(httpRequest.getHeader("Authorization"));
            if (validClientCert && validAuthToken) {
                logger.debug("{} cert and Auth token are good!", CLIENT_CERT_NAME);
                chain.doFilter(request, response);
                return;
            }
        } catch (Exception e) {
            responseCode = 403;
            responseException = new AuthException("certificate or auth token is missing or invalid", "Must provide a valid client certificate and auth token");
            sendResponse(responseCode, responseException, httpResponse);
        }
    }

    @Override
    public void destroy() {
        throw new UnsupportedOperationException();
    }
}

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Spring MVC строится вокруг одного конкретного сервлета с внутренней диспетчеризацией на основе конфигураций контроллера пружины.Как только запрос достигает централизованного диспетчера, он проверяет сопоставления и направляет вызов конкретному контроллеру.Если нет отображений, это вызывает исключение.Фильтр, который является частью спецификации сервлета, слишком «низкоуровневый», он может перехватить только «общий» запрос для запуска MVC, поэтому вы не сможете заставить его работать с абстракцией фильтра, потому что он не имеет ничего общегос внутренней маршрутизацией конечных точек Spring mvc.

Однако вы можете использовать перехватчики, специфичные для Spring, для перехвата вызовов определенных контроллеров.Код перехватчиков выполнит работу на основе сертификатов.

В этом случае сопоставление URL будет автоматически проверено средой Spring MVC.

Если для сопоставления нет контроллеров Spring,очевидно, их перехватчики не будут вызваны, и 404 будет немедленно возвращено.

Вы можете найти учебник по использованию этих перехватчиков Здесь

Но в итоге они действуют так же, какФильтры с основным отличием в том, что они «на уровне» инфраструктуры Spring MVC, а не на уровне сервлетов (намного ниже).

Другое возможное решение (хотя и не связанное напрямую с вашим вопросом) - использованиеSpring Security, на вопрос, похоже, это может быть правильной абстракцией для работы с сертификатами, но это только примечание

0 голосов
/ 22 сентября 2018

Я думаю, вы могли бы неправильно понять или неправильно понять фильтр сервлетов Java и компонент Spring.

Но ваша проблема может быть решена двумя способами:

  • с использованием фильтра сервлетов.
  • с использованием перехватчика пружины.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...