【发布时间】: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