'스프링 시큐리티 ajax로그인'에 해당되는 글 1건

  1. 2009.09.29 스프링 시큐리티 3.0m2 그리고 ajax 로그인..
봄싹2009.09.29 01:58
현재 봄싹에선 스프링 시큐리티 3.0m2 버전을 사용중이다.
그런데 새로운 디자인에 ajax 로그인이 생기면서 문제가 좀 발생했다..

지금 사용 하는 유저 인증 관련 필터는..
UsernamePasswordAuthenticationProcessingFilter 이놈이 다..
UserDetailsService을 구현 해서 . DaoAuthenticationProvider 이놈을 통해서
유저 인증을 한다 .

문제는 인증이 문제가 아니다 ..

<form-login login-page="/login.do"
            authentication-failure-url="/login.do?login_error=t"
            default-target-url="/mypage/index.do" />

기존에 이런식으로 설정이 되어 있다 .
대충 결론 부터 이야기 하면... 로그인이 성공을 하면 .. /mypage/index.do 로 리다이렉트..
실패면 /login.do?login_error=t 이렇게 리다이렉트..

ajax에 리다이렉트라... 이게 웬말인가..
하지 말라는거야 머야 ? ㅡㅡ;;

그래서 좀 살펴 봤다..

UsernamePasswordAuthenticationProcessingFilter의 아버지를 보면 AbstractAuthenticationProcessingFilter 이놈인데..
이놈의 doFilter 를 살펴보면..


이러하다 .. 빨간곳에서.. (저놈은 UsernamePasswordAuthenticationProcessingFilter이 구현 했다.. ) 로그인 인증을 한다.
그리고 실패면 .. AuthenticationException  이놈을 throw 하고.. 아니면.. 일단 다음 진행 단계로 넘어간다.

1. 실패시..
unsuccessfulAuthentication 이놈을 살펴보면.. SimpleUrlAuthenticationFailureHandler 요놈을 핸들러로 .. 사용중인데..
forwardToDestination 이값을 변경하여
 if (forwardToDestination) {
                request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
            } else {
                RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext);
            }

포워드와 리다이렉트를 할 수 구별할수 잇다..

*** 여기서 리다이렉트가 왜 안되냐면 현재 봄싹에선 ajax 호출에 대해서 ..
header 에 정보를 담아서 보내는데.
결국 리다이렉트로 넘어가면 header 정보가 없어진다.. (웃긴 이야기지만 ..  ie6.0 / 크롬/ 에선 안사라짐..
ff 만 header 정보 사라짐.. )


2.성공시..
성공시가 successfulAuthentication 가장 골때리는데..
SavedRequestAwareAuthenticationSuccessHandler 결국 이놈이 처리 하긴 하는데..

  @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws ServletException, IOException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);

        if (savedRequest == null) {
            super.onAuthenticationSuccess(request, response, authentication);

            return;
        }

        if (isAlwaysUseDefaultTargetUrl() || StringUtils.hasText(request.getParameter(getTargetUrlParameter()))) {
            requestCache.removeRequest(request, response);
            super.onAuthenticationSuccess(request, response, authentication);

            return;
        }

        // Use the SavedRequest URL
        String targetUrl = savedRequest.getFullRequestUrl();
        logger.debug("Redirecting to SavedRequest Url: " + targetUrl);
        RedirectUtils.sendRedirect(request, response, targetUrl, isUseRelativeContext());
    }


보시다 싶이.. 무조건 리다이렉트를 한다..

일단 문제 파악은.. 여기서 끝.. ;;

생각해본 해결 방안은 크게 3가지 정도가 있다..
1. 헨들러를 각각 구현을 해주던가..
2. 아니면...  UsernamePasswordAuthenticationProcessingFilter 이놈을 새로 거시기 하던가 .
3. 약간의 꽁수이긴 헌데.. xxx.do?spring-security-redirect=해당url 이런식으로 ajax 로그인과 비 ajax로그인의 url을 다르게 줘서 구현하던가.. fail에대해선.. forwardToDestination true로 주고 말이지..

일단.. 생각은..

xml에.
    <form-login login-page="/login.do"
            authentication-failure-url="/loginFailProcess.do"
            default-target-url="/loginSuccessProcess.do" />

이렇게 등록하고... 해당 컨트럴에서 .. 먼가 처리하려고 생각중.. 그러니 3번은 아닌거다..
1번 아니면 2번인데 정우형이 자꾸 필터를 하고 싶어한다..

구현은 내일로.. 벌써 2시다 ㅡㅡ;;
Posted by is윤군

댓글을 달아 주세요