Безопасность Spring добавляет ApplicationEventListener в ExpiredJwtException - PullRequest
0 голосов
/ 05 ноября 2018

Я реализовал AuthenticationFailureListener для неудачного входа в систему с помощью ApplicationListener<AuthenticationFailureBadCredentialsEvent>, и все мои события Bad Credentials расположены в одном и том же классе, очень удобно, я пытался добавить прослушиватель к ExpiredJwtException или SignatureException, но я не могу понять, какое событие вызвало, я пытался -

@Component
public class ApplicationEventListener implements ApplicationListener<ApplicationEvent>{

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println(event.toString()); //not printed when ExpiredJwtException thrown
    }
}

чтобы поймать все ApplicationEvent, но когда происходит одно из этих исключений, метод onApplicationEvent не срабатывает. Я могу поймать эти исключения, но я хочу обрабатывать их глобально, как BadCredentialsException обрабатывается AuthenticationFailureBadCredentialsEvent. Попробовал AuthenticationFailureExpiredEvent -

@Component
public class ApplicationEventListener implements ApplicationListener<AuthenticationFailureExpiredEvent>{

    @Override
    public void onApplicationEvent(AuthenticationFailureExpiredEvent event) {
        System.out.println("Expired!!"); //same result
    }
}

но все еще не работает.

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Я не уверен в этом, мне придется проверить источник, но: может случиться так, что событие приложения не отправлено для ExpiredJwtException или SignatureException.

Возможные решения:

  1. Опубликуйте событие самостоятельно: как вы упомянули, вы можете перехватить эти исключения, поэтому простым решением было бы перехватить их и затем сгенерировать желаемое событие. Вам просто нужно автоматически подключить ApplicationEventPublisher и затем позвонить publishEvent(event).

  2. Используйте Filter для отлова и обработки исключений в одном месте.

Пример решения 2:

public class AuthFailureFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(request, response);
        } catch (ExpiredJwtException | SignatureException exception) {
            handle(exception);
        }
    }
}
0 голосов
/ 05 ноября 2018

Я думаю, что самый простой способ опубликовать ApplicationEvent при перехвате исключений - использовать ApplicationEventPublisher. Нет необходимости реализовывать ApplicationEvent, используя этот метод, поскольку он оборачивает любой объект в PayloadApplicationEvent, который вы можете использовать в вашем ApplicationEventListener, и воздействует на него. Это работает с весны 4.2 и вот официальная ссылка: https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2

...