【问题标题】:Cannot catch Exception in Java无法在 Java 中捕获异常
【发布时间】:2021-10-14 15:11:06
【问题描述】:

我通过启发 Baeldung 的 Prevent Brute Force Authentication Attempts with Spring Security 页面,为我的登录服务实施了暴力阻止机制,如下所示:

@Service
@RequiredArgsConstructor
public class LoginServiceImpl implements LoginService {

    private final UserService userService;
    private final LoginAttemptService loginAttemptService;

    public UserTokenDTO login(final LoginRequest request) {        

        if(!user.isValid) {
            throw new InvalidCredentialsException();
        }
        // code omitted for brevity
    }
}

当用户未通过验证时,LoginService 会抛出 InvalidCredentialsException(),然后我试图在 AuthenticationFailureListener 类中捕获此异常:

@Component
public class AuthenticationFailureListener implements 
    ApplicationListener<AuthenticationFailureBadCredentialsEvent> {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private LoginAttemptService loginAttemptService;

    @Override
    public void onApplicationEvent(final AuthenticationFailureBadCredentialsEvent e) {
        final String xfHeader = request.getHeader("X-Forwarded-For");
        if (xfHeader == null) {
            loginAttemptService.loginFailed(request.getRemoteAddr());
        } else {
            loginAttemptService.loginFailed(xfHeader.split(",")[0]);
        }
    }
}

当出现错误时,会调用loginAttemptService.loginFailed() 方法。但是,我无法在onApplicationEvent() 中捕获异常。我尝试过使用不同的事件类型,但对于某些事件,例如ApplicationEvent 它在每个事件上触发,我应该仅在抛出 InvalidCredentialsException 时用户未通过身份验证时触发它。

进行搜索后,我发现我需要进行配置,以便 Spring Security 在失败或成功时捕获这些事件。但是定义不清楚,我想也许我可以通过在我的AuthenticationFailureListener 类中使用正确的事件类型来捕捉事件。我也有一个事件处理程序类,但我不确定它是否有帮助。

更新:这是我的SecurityConfig。我仍然无法触发AuthenticationFailureBadCredentialsEvent,也无法获得任何异常onApplicationEvent

@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    AuthenticationFailureHandler eventAuthenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }

    private final AuthenticationFailureHandler eventAuthenticationFailureHandler;

    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .formLogin().failureHandler(eventAuthenticationFailureHandler)
                .and()
                .httpBasic();
    }
}

【问题讨论】:

  • 还有其他人有异常处理或 Spring Security 方面的经验吗?
  • 您的AuthenticationFailureListener 不会捕获异常。如果您希望它捕获事件,您应该使用ApplicationContext 发出事件。如果您使用AuthenticationManager 对用户进行身份验证,通常会为您执行此操作。看看ProviderManager 源代码。
  • 非常感谢,但我没有经验。你能把这个作为答案发布吗?提前致谢。

标签: java spring spring-boot spring-security event-handling


【解决方案1】:

正如this answer中所写:

如果身份验证成功,将通过应用程序上下文发布一个 InteractiveAuthenticationSuccessEvent。 如果身份验证不成功,则不会发布任何事件,因为这通常会通过 AuthenticationManager 特定的应用程序事件进行记录。

【讨论】:

  • 非常感谢朋友。实际上我已经阅读了该线程并实施了类似的方法。 但是我无法理解 “...您应该能够以这种方式配置它” 部分。那么,您能否澄清一下我应该在哪里定义它?顺便说一句,我有一个 Spring Boot 应用程序。
  • @Henry 通常你把.failureHandler(eventAuthenticationFailureHandler) 放在你的AuthenticationFilter bean 中。我不知道你必须把它放在哪里,这取决于你如何配置你的 spring 安全上下文。如果你能贴出来,我会帮你弄清楚。请记住,您的 SimpleUrlAuthenticationFailureHandler 必须是一个 bean,您可以通过将 @Component 添加到您的 Handler 或在您的配置类中使用 @Bean 来做到这一点
  • 实际上我的项目中没有Apring Security配置,这个暴力阻止部分是我项目中Spring Security的第一部分。那么,假设没有配置,你能给我一个例子并解释我应该在项目中添加或实现什么吗?
  • 一切都取决于您的需求,Spring Security 配置是一个相当大的话题。在此播放列表中,您将找到一些实际示例。 youtube.com/…也看一下spring security reference docs.spring.io/spring-security/site/docs/current/reference/…
  • 最基本的配置是这个,github.com/dangeabunea/RomanianCoderExamples/blob/master/…,你可以在我链接的播放列表中的其中一个视频中找到解释(应该是第十一个)。在您要使用配置的情况下,failureHandler 会像这样在 httpBasic() 之后执行 `.httpBasic().failureHandler(eventAuth....);`
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
  • 2021-08-07
相关资源
最近更新 更多