我已经尝试了一整天,让我的自定义身份验证失败处理程序与Spring 3.1.3一起使用.
我认为它配置正确
我的实现是这样的
public class LoginFailureHandler implements AuthenticationFailureHandler {
private static final Logger log = LoggerFactory.getLogger(LoginFailureHandler.class);
public LoginFailureHandler() {
log.debug("I am");
}
@Autowired
private ObjectMapper customObjectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request,HttpServletResponse response,AuthenticationException exception) throws IOException,ServletException {
log.debug("invalid login");
User user = new User();
user.setUsername("invalid");
try (OutputStream out = response.getOutputStream()) {
customObjectMapper.writeValue(out,user);
}
}
}
在控制台中,我看到了
2013-04-11 14:52:29,478 DEBUG LoginFailureHandler - I am
所以它被加载了.
使用错误的用户名或密码,当抛出BadCredentialsException时,我看不到无效登录.
永远不会调用Method of onheuthenticationFailure.
相反,服务会一次又一次地将浏览器重定向到/ rest / login …
编辑
2013-04-11 15:47:26,411 DEBUG de.pentos.spring.LoginController - Incomming login chuck.norris,norris
2013-04-11 15:47:26,412 DEBUG o.s.s.a.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2013-04-11 15:47:26,415 DEBUG o.s.s.a.d.DaoAuthenticationProvider - Authentication Failed: password does not match stored value
2013-04-11 15:47:26,416 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public de.pentos.spring.User de.pentos.spring.LoginController.login(de.pentos.spring.User)]: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-04-11 15:47:26,419 DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public de.pentos.spring.User de.pentos.spring.LoginController.login(de.pentos.spring.User)]: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-04-11 15:47:26,419 DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public de.pentos.spring.User de.pentos.spring.LoginController.login(de.pentos.spring.User)]: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-04-11 15:47:26,426 DEBUG o.s.web.servlet.DispatcherServlet - Could not complete request
org.springframework.security.authentication.BadCredentialsException: Bad credentials
这种情况发生在调试模式中
我的错误在哪里?
从登录控制器,您通常应该使用action =“j_spring_security_check”method =“post”来提供简单的登录表单.当用户提交该表单时,配置的安全筛选器(即UsernamePasswordAuthenticationFilter)将拦截该请求并处理身份验证.您不必在控制器方法中自己实现该逻辑.
您确实使用ProviderManager(它是自动连接的AuthenticationManager接口的实现).您犯的错误是您尝试重写已经实现的逻辑并在auth过滤器中进行彻底测试.这本身就很糟糕,但即使这样做也是错误的.您只需从复杂的逻辑中选择几行,除此之外您还会忘记例如调用会话策略(以防止会话固定攻击和处理并发会话).原始实现调用AuthenticationFailureHandler
同样,你也忘记了你的方法,这就是你原来问题的问题的原因.
因此,您最终会得到一个未经测试的脆弱解决方案,而不是与框架很好地集成,以充分利用其强大的功能和全部容量.正如我所说,您在答案中发布的配置是一个明确的改进,因为它使用框架提供的过滤器进行身份验证.保留该配置并删除LoginController.login(),无论如何都不会被发送到/ rest / login的请求调用.
一个更基本的问题是,如果您实施RESTful服务,它是否真的是一个使用会话和基于表单的登录机制的好方法. (在基于表单的登录时,我的意思是客户端以任何格式发送其凭证一次,然后通过有状态会话对后续请求进行身份验证.)使用REST服务,保持所有无状态并重新验证每个新请求更为普遍通过http标头携带的信息.