如何使用spring security从失败的登录中获取用户名?

我们使用的是spring security 3.0.5,Java 1.6和Tomcat 6.0.32。 在我们的.xml配置文件中,我们得到了:

 

我们的authenticationFailureHandler定义为:

    /index.html?authenticationFailure=true    

Java的

  @RequestMapping(params={"authenticationFailure=true"}, value ="/index.html") public String handleInvalidLogin(HttpServletRequest request) { //... How can I get the username that was used??? // I've tried: Object username = request.getAttribute("SPRING_SECURITY_LAST_USERNAME_KEY"); Object username = request.getAttribute("SPRING_SECURITY_LAST_USERNAME"); // deprecated } 

所以我们将所有BadCredentialsExceptions指向index.htmlIndexController 。 在IndexController我想获取用于失败登录尝试的username 。 我怎样才能做到这一点?

好的,所以答案结果是非常简单的,但据我所知,没有经过深入讨论或记录。

这就是我必须做的所有事情(没有任何配置只是创建这个类)…

 import org.apache.log4j.Logger; import org.springframework.context.ApplicationListener; import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; import org.springframework.stereotype.Component; @Component public class MyApplicationListener implements ApplicationListener { private static final Logger LOG = Logger.getLogger(MyApplicationListener.class); @Override public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { Object userName = event.getAuthentication().getPrincipal(); Object credentials = event.getAuthentication().getCredentials(); LOG.debug("Failed login using USERNAME [" + userName + "]"); LOG.debug("Failed login using PASSWORD [" + credentials + "]"); } } 

我离spring的安全专家很远,所以如果有人读到这个并知道我们不应该这样做的理由,或者知道一个更好的方式我会喜欢听到它。

我是这样做的:

  1. 创建了一个扩展SimpleUrlAuthenticationFailureHandler的类

  2. 覆盖onAuthenticationFailure方法,该方法接收HttpServletRequest作为参数。

  3. request.getParameter("username") ,其中"username"是我的HTML表单中输入的名称。

您可以改为提供自己的DefaultAuthenticationEventPublisher版本并覆盖publishAuthenticationFailure方法。

此解决方案似乎没有太多信息,但如果在Spring Security配置中设置failureForwardUrl ,则会转发到错误页面而不是重定向。 然后,您可以轻松检索用户名和密码。 例如,在你的配置中添加: .and().formLogin().failureForwardUrl("/login/failed") (* url必须与登录页面url不同)

在您的登录控制器中,以下内容:

 @RequestMapping(value = "/login/failed") public String loginfailed(@ModelAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY) String user, @ModelAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY) String password) { // Your code here } 

SPRING_SECURITY_FORM_USERNAME_KEY,SPRING_SECURITY_FORM_PASSWORD_KEY是默认名称,但您也可以在FormLoginConfigurer中设置它们:

 .and().formLogin().usernameParameter("email").passwordParameter("password").failureForwardUrl("/login/failed") 

我发现这对我有用。 不幸的是,我仍然没有在SpringSecurity文档中找到它的确切位置:

在任何操作中,您都可以检查上次使用的用户名(无论登录失败与否):

  String username = (String) request.getSession().getAttribute("SPRING_SECURITY_LAST_USERNAME");