2012-10-17 79 views
1

我需要在调用authenticationManager进行身份验证之前在登录表单上进行一些验证。已经能够实现它在一个现有的职位帮助 - How to make extra validation in Spring Security login form?春季安全为自定义登录表单执行验证

有人可以请建议我,我是否遵循正确的方法或错过了什么?特别是,我不太清楚如何显示错误信息。 在筛选器中,我使用验证器对登录字段执行验证,并且在出现错误的情况下,我抛出一个Exception(它扩展了AuthenticationException)并封装了Errors对象。一个getErrors()方法被提供给异常类来检索错误。

由于在任何身份验证异常的情况下,失败处理程序会将该异常存储在会话中,因此在我的控制器中,我检查会话中存储的异常,并且如果发生异常,请使用错误填充绑定结果从我的定制的异常检索的对象(后检查的AuthenticationException的运行时实例)

下面是我的代码按扣 -

LoginFilter类

public class UsernamePasswordLoginAuthenticationFilter extends 
     UsernamePasswordAuthenticationFilter { 

    @Autowired 
    private Validator loginValidator; 

    /* (non-Javadoc) 
    * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 
    */ 
    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, 
      HttpServletResponse response) throws AuthenticationException { 

     Login login = new Login(); 
     login.setUserId(request.getParameter("userId")); 
     login.setPassword(request.getParameter("password")); 
     Errors errors = new BeanPropertyBindingResult(login, "login"); 
     loginValidator.validate(login, errors); 
     if(errors.hasErrors()) { 
      throw new LoginAuthenticationValidationException("Authentication Validation Failure", errors); 
     } 
     return super.attemptAuthentication(request, response); 
    } 
} 

控制器

@Controller 
public class LoginController { 

    @RequestMapping(value="/login", method = RequestMethod.GET) 
    public String loginPage(@ModelAttribute("login") Login login, BindingResult result, HttpServletRequest request) { 

     AuthenticationException excp = (AuthenticationException) 
       request.getSession().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); 
     if(excp != null) { 
      if (excp instanceof LoginAuthenticationValidationException) { 
       LoginAuthenticationValidationException loginExcp = (LoginAuthenticationValidationException) excp; 
       result.addAllErrors(loginExcp.getErrors()); 
      } 
     } 
     return "login"; 
    } 

    @ModelAttribute 
    public void initializeForm(ModelMap map) { 
     map.put("login", new Login()); 
    } 

这部分的控制器来检查异常的实例,然后取出错误的对象,看起来不干净的方法。我不确定这是处理这个问题的唯一方法,还是有人以任何其他方式接近它?请提供您的建议。

谢谢!

+2

为什么你想/需要验证登录输入?证书不错,或者不是。似乎很有自我验证... – pap

+0

沿着同样的路线,是不是也想要在登录尝试之外验证登录凭证超越成功或失败,因为您正在给可能的攻击者提供比需要更多的信息? – dardo

回答

0
@RequestMapping(value = "/login", method = RequestMethod.GET) 
public ModelAndView signInPage(
    @RequestParam(value = "error", required = false) String error, 
    @RequestParam(value = "logout", required = false) String logout) { 
     ModelAndView mav = new ModelAndView(); 
     //Initially when you hit on login url then error and logout both null 
     if (error != null) { 
      mav.addObject("error", "Invalid username and password!"); 
     } 

     if (logout != null) { 
      mav.addObject("msg", "You've been logged out successfully."); 
     } 
     mav.setViewName("login/login.jsp"); 
} 

现在,如果万一登录成为unsuccessfull然后再重新打这个网址与错误的URL追加如春的安全文件设置失败URL。 春季安全文件:-authentication-failure-url="/login?error=1" 那么您的网址成为url/login?error=1 然后自动signInPage方法调用,并与一些错误value.Now误差不为空,你可以设置任意字符串对应的URL,我们可以使用这些以下标签上的JSP显示: -

<c:if test="${not empty error}"> 
    <div class="error">${error}</div> 
</c:if>