2012-07-16 6 views
0

스프링 보안 (3.1)을 사용하여 응용 프로그램을 개발 중이고 다음과 같은 문제가 발생했습니다. 사용자가 로그 아웃 할 때 보안 페이지에서 로그 아웃했는지 여부에 따라 일부 맞춤 URL로 리디렉션하려고합니다. 나는 다음과 같이 보이는 사용자 정의 LogoutHandler을 썼다 :스프링 보안 사용자 정의 LogoutSuccessHandler가 이상한 인증 객체를 가져옴

@Override 
public void onLogoutSuccess(HttpServletRequest request, 
     HttpServletResponse response, Authentication authentication) 
     throws IOException, ServletException { 


    String refererUrl = request.getHeader("Referer"); 
    if (requiredAuthentication(refererUrl, authentication)) { 
     response.sendRedirect(request.getContextPath()); 
    } else { 
     response.sendRedirect(refererUrl); 
    } 
} 

private boolean requiredAuthentication(String url, Authentication authentication){ 
    return !getPrivilegeEvaluator().isAllowed(url, authentication); 
} 

따라서, 사용자는 자신이 로그 아웃과 같은 URL로 리디렉션 비 보안 페이지에서 로그 아웃하고, 그는에서 ouf 로그인하면 때 보안 페이지에서 색인 페이지로 이동합니다. 문제는 메서드에 오는 인증 개체가 항상 인증된다는 것입니다 (메서드가 사용자가 지정한대로 로그 아웃 한 후에도 호출되는 경우에도 마찬가지입니다). 내 보안 컨텍스트 :

<http use-expressions="true" disable-url-rewriting="true" request-matcher-ref="requestMatcher" > 


    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="https" /> 
    <intercept-url pattern="/dashboard/**" access="hasRole('ROLE_OWNER')" requires-channel="https" /> 
    <intercept-url pattern="/**" access="permitAll"/> 

    <form-login login-page="/login" 
       authentication-success-handler-ref="successHandler" 
       authentication-failure-url="/login" 
       login-processing-url="/validate" /> 

    <logout logout-url="/logout" invalidate-session="true" success-handler-ref="logoutSuccessHandler" /> 

    <remember-me services-ref="rememberMeServices" key="KEY" use-secure-cookie="false" /> 

    <session-management session-fixation-protection="migrateSession"> 
     <concurrency-control max-sessions="1" /> 
    </session-management> 

</http> 

당신이 logoutSuccessHandler에 gettig 때받은 인증은 여전히 ​​유효 왜 어떤 생각을 가지고 있습니까? 필드가 final (isAuthenticated는 제외하지만 isAllowed() 메서드로 검사되지 않습니다.)이기 때문에이 객체를 편집 할 수 없습니다.

답변

3

Spring Security 소스 코드를 보면 LogoutFilter는 SecurityContextHolder , 로컬 변수에 유지하고 SecurityContextLogoutHandler를 통해 홀더에서 제거합니다. 모든 LogoutHandler를 호출하면 LogoutSuccessHandler를 호출하고 Authentication 객체를 전달합니다.

유효한 경우에도 더 이상 SecurityContextHolder에 없으므로 Spring의 경우 사용자는 로그 아웃됩니다.

+0

예, 이미 LogoutSuccessHandler가 LogoutSuccessHandler가 Logout 전에 Authentication 객체를 가져 왔기 때문에 모든 grant 등이 있습니다. LogoutSuccessHandler 내부에서 isAllowed()에 대한 Authentication을 사용하면 true를 반환하고, 논리적으로 false를 반환해야한다고 생각합니다 (이미 로그 아웃되었으므로). 다른 방법으로 내 문제를 해결했지만 wrirte는 정확합니다. 그래서 대답을 표시합니다 :) – Mat

관련 문제