如何使用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.html
和IndexController
。 在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的安全专家很远,所以如果有人读到这个并知道我们不应该这样做的理由,或者知道一个更好的方式我会喜欢听到它。
我是这样做的:
-
创建了一个扩展
SimpleUrlAuthenticationFailureHandler
的类 -
覆盖onAuthenticationFailure方法,该方法接收
HttpServletRequest
作为参数。 -
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");