1

認証のために authenticationManager を呼び出す前に、ログインフォームでいくつかの検証を行う必要があります。1 つの既存の投稿の助けを借りてそれを達成することができました - Spring Security ログインフォームで追加の検証を行うには?

私が正しいアプローチに従っているのか、それとも何かを見逃しているのか、誰かが私に提案してもらえますか? 特に、エラーメッセージの表示方法がよくわかりませんでした。フィルターでは、バリデーターを使用してログイン フィールドの検証を実行し、エラーが発生した場合は、(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());
    }

例外のインスタンスをチェックしてから 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 にエラーが追加されてこの URL に再びヒットします。Spring セキュリティ ファイル:-authentication-failure-url="/login?error=1" 次に、URl がurl/login?error=1 自動的に signInPage メソッドが呼び出され、いくつかのエラー値が返されます。現在、エラーは null ではなく、url に対応する任意の文字列を設定でき、次のタグを使用して jsp に表示できます:-

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