Как с помощью Spring Security определить, должен ли текущий запрос API аутентифицироваться или нет? - PullRequest
0 голосов
/ 28 мая 2020

С Spring Security вы можете иметь конечные точки publi c api, доступные всем, и конечные точки, которые необходимо аутентифицировать перед получением ответа. В моем приложении пользователи проходят аутентификацию с помощью токена jwt. Прямо сейчас для авторизованных пользователей токен всегда проверяется, независимо от того, получает ли конечная точка publi c api запрос или нет.

Я хотел бы знать, как проверить, является ли текущая конечная точка конечной точкой publi c или аутентифицированной; таким образом я могу изменить код, чтобы проверка токена выполнялась только тогда, когда конечная точка требует аутентификации .

Я мог бы добавить все конечные точки publi c в хэш-набор и сравнить текущую конечную точку запроса с конечными точками publi c, но это неэффективно, а также некоторые конечные точки publi c содержат подстановочные знаки (**), так что сравнение будет немного хлопотным.

Это единственная информация, которую я смог найти:

Spring Security - проверьте, безопасен ли веб-адрес / protected

, но это примерно JSP.

Я тоже не могу получить информацию о запросе от SecurityContextHolder.getContext(). Я предполагаю, что я должен получить информацию из org.springframework.security.config.annotation.web.builders.HttpSecurity, потому что это тот же класс, который используется для определения конечных точек, не требующих аутентификации. (с помощью anthMatchers (). allowedall ()). Но я не знаю, какой метод вызывать, и я не уверен, что HttpSecurity можно даже автоматически подключить к другому классу. Кто-нибудь может дать мне несколько указателей?

Спасибо

1 Ответ

0 голосов
/ 02 июня 2020

Предполагая, что вы используете отдельный фильтр для проверки токена, вы можете избежать проверки токена для конечных точек publi c, переопределив защищенное логическое значение shouldNotFilter (запрос HttpServletRequest) метода OncePerRequestFilter в ваш JwtTokenFilter. По умолчанию этот метод всегда возвращает false. Таким образом, все запросы будут отфильтрованы. Переопределение этого метода для возврата true для конечных точек publi c даст вам желаемую функциональность. А для проверки запросов с подстановочными знаками (**) вы можете использовать AntPathRequestMatcher. Итак, вы можете сделать что-то вроде ниже.

public class JwtTokenFilter extends OncePerRequestFilter {
    private static RequestMatcher requestMatcher;

    public static void ignorePatterns(String... antPatterns) {
        List<RequestMatcher> matchers = new ArrayList<>();
        for (String pattern : antPatterns) {
            matchers.add(new AntPathRequestMatcher(pattern, null));
        }
        requestMatcher = new OrRequestMatcher(matchers);
    }

    static {
        final String[] publicEndPoints = {"/public-api/**","/resources/**"};
        ignorePatterns(publicEndPoints);
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return requestMatcher.matches(request);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
    ....
    }
}

Надеюсь, это поможет !!

...