1

在调用 authenticationManager 进行身份验证之前,我需要对登录表单进行一些验证。已经能够在一篇现有帖子的帮助下实现它 -如何在 Spring Security 登录表单中进行额外验证?

有人可以建议我是遵循正确的方法还是错过了什么?特别是,我不太清楚如何显示错误消息。在过滤器中,我使用验证器对登录字段进行验证,如果出现错误,我会抛出一个异常(它扩展了 AuthenticationException)并封装了 Errors 对象。为异常类提供了一个 getErrors() 方法来检索错误。

由于在任何身份验证异常的情况下,失败处理程序将异常存储在会话中,因此在我的控制器中,我检查存储在会话中的异常,如果存在异常,则使用从我的自定义异常(在检查 AuthenticationException 的运行时实例之后)

以下是我的代码快照 -

登录过滤器类

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());
    }

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

谢谢!

4

1 回答 1

1
@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");
}

现在,如果登录不成功,那么它将再次点击此 url,并在其 url 中附加错误,就像在 spring 安全文件中设置失败 url 一样。Spring 安全文件:-authentication-failure-url="/login?error=1" 然后您的 URl 变为url/login?error=1 Then 自动 signInPage 方法将调用并带有一些错误值。现在错误不为空,您可以设置与 url 对应的任何字符串,我们可以使用以下标签在 jsp 上显示:-

<c:if test="${not empty error}">
   <div class="error">${error}</div>
</c:if>
于 2015-09-07T09:34:09.170 回答