복붙노트

[SPRING] remember-me 및 authentication-success-handler

SPRING

remember-me 및 authentication-success-handler

로그인 성공과 페이지로 리디렉션하는 데 이상한 문제가 있습니다.

아래는 내 봄 보안 구성입니다.

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/login.hst**" access="anonymous or authenticated" />
    <intercept-url pattern="/**/*.hst" access="authenticated" />
    <form-login login-page="/login.hst"
        authentication-failure-url="/login.hst?error=true"
        authentication-success-handler-ref="loginSucessHandler" />
    <logout invalidate-session="true" logout-success-url="/home.hst"
        logout-url="/logout.hst" />
    <remember-me key="jbcpHaverERP" authentication-success-handler-ref="loginSucessHandler"/>
    <session-management>
    <concurrency-control max-sessions="1" />
</session-management>
</http>

LoginSuessHandler 클래스 :

@Service
public class LoginSucessHandler extends
        SavedRequestAwareAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws ServletException, IOException {
            ...
        super.setUseReferer(true);
        super.onAuthenticationSuccess(request, response, authentication);
    }

}

이제 성공하면 요청한 페이지로 리디렉션하는 문제가 발생했습니다. 내가 직접 보안 URL을 참조하면 스프링이 나를 로그인 페이지로 리디렉션하고 원래 요청 된 링크에 성공적으로 로그인하게됩니다. 사용자가 이전에 remember-me를 선택한 다음 브라우저를 닫고 직접 URL을 요청한 경우 올바르게 인증되었지만 요청한 페이지 스프링으로 리디렉션하지 않고 /로 리디렉션하는 경우에는 작동하지 않습니다. 로그 및 일부 스프링 소스 코드를 확인하고 대상 URL을 결정할 수 없다는 것을 알았습니다.

참조를 설정하려고했지만 referer 값이 null입니다. 하지만 하나의 이상한 점은 제가 봄 - 보안 설정에서 기억 장치 구성에서 authentication-success-handler를 제거했다면 작동한다는 것입니다.

    <remember-me key="jbcpHaverERP" authentication-success-handler-ref="loginSucessHandler"/>

문제를 파악할 수 없습니다. 인증 성공 핸들러 구현은 폼 로그인과 기억을 위해 다른 것이 필요합니까?

해결법

  1. ==============================

    1.사용자가 실제로 요청할 때 인증이 수행된다는 점에서 폼 로그인과 다릅니다. 양식 로그인의 경우 사용자는 먼저 로그인 페이지로 리디렉션되어야하며 로그인 양식을 제출해야합니다. 그런 다음 원래 대상 (일반적으로 세션에 캐시 됨)으로 리디렉션됩니다. 그래서 form-login은 리다이렉트를 필요로하지만, remember-me는 리다이렉트를 요구합니다. remember-me 요청을 사용하면 사용자를 인증 할 수 있으며 요청은 개입없이 진행될 수 있습니다.

    사용자가 실제로 요청할 때 인증이 수행된다는 점에서 폼 로그인과 다릅니다. 양식 로그인의 경우 사용자는 먼저 로그인 페이지로 리디렉션되어야하며 로그인 양식을 제출해야합니다. 그런 다음 원래 대상 (일반적으로 세션에 캐시 됨)으로 리디렉션됩니다. 그래서 form-login은 리다이렉트를 필요로하지만, remember-me는 리다이렉트를 요구합니다. remember-me 요청을 사용하면 사용자를 인증 할 수 있으며 요청은 개입없이 진행될 수 있습니다.

    AuthenticationSuccessHandler의 주된 목적은 인증 후에 탐색 흐름을 제어하는 ​​것이므로 일반적으로 기억 장치가있는 곳을 전혀 사용하지 않을 것입니다. 저장된 요청을 사용할 수 없으므로 SavedRequestAwareAuthenticationSuccessHandler를 사용하는 것은 좋지 않습니다. 저장된 요청이 없으면 기본적으로 "/"로 리디렉션됩니다.

    remember-me 로그인 중에 일부 기능을 추가하기 만하면, 리디렉션 또는 전달을 수행하지 않고 직접 AuthenticationSuccessHandler 인터페이스를 구현할 수 있습니다. 앞서 설명했듯이 현재 요청은 로그인 양식 (일반적으로 URL j_spring_security_check)을 제출하고 응용 프로그램 내의 URL을 요청하는 것이 아니기 때문에 양식 로그인에 동일한 구현을 사용할 수 없습니다. 그래서 form-login을위한 리다이렉트가 필요합니다.

  2. ==============================

    2.오히려 ApplicationListener를 사용하여 InteractiveAuthenticationSuccessEvent 이벤트를 찾으십시오.

    오히려 ApplicationListener를 사용하여 InteractiveAuthenticationSuccessEvent 이벤트를 찾으십시오.

    InteractiveAuthenticationSuccessEvent에는 필터, 즉 UsernamePasswordAuthenticationFilter (form logins) 및 RememberMeAuthenticationFilter (로그인 기억) 인 generatedBy 속성이 있습니다.

    @Component
    class AuthenticationApplicationListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
    
      @Override
      void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
        //do something
      }
    
    }
    

    rememberMe에 대한 AuthenticationSuccessHandler의 사용자 정의 구현을 사용하면 문제가 발생할 수 있습니다. RememberMeAuthenticationFilter의 흐름을 살펴보십시오. successHandler가 사용되면 필터 체인이 무시됩니다.

  3. ==============================

    3.로그인 양식과 remember-me에 대해 다른 authentication-success-handler를 구현해야합니다. remeber-me 핸들러에서 리디렉션을 수행하려면 SimpleUrlAuthenticationSuccessHandler를 사용하고 DefaultTargetUrl을 설정할 수 있습니다.

    로그인 양식과 remember-me에 대해 다른 authentication-success-handler를 구현해야합니다. remeber-me 핸들러에서 리디렉션을 수행하려면 SimpleUrlAuthenticationSuccessHandler를 사용하고 DefaultTargetUrl을 설정할 수 있습니다.

    public class RememberMeAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
        Authentication authentication) throws IOException, ServletException {
    
        // ...
    
        super.setAlwaysUseDefaultTargetUrl(true);
        super.setDefaultTargetUrl(request.getRequestURL().toString());
        super.onAuthenticationSuccess(request, response, authentication);
    }
    
  4. ==============================

    4.AuthenticationSuccessHandler를 사용하면 작동하지 않습니다. 다른 답변에서 언급했듯이, 스프링 보안 필터 체인은 무시 될 것입니다! 작동하는 것은 ApplicationListener를 사용하는 것입니다. 그러나 사용자를 기억하여 사용자가 인증 되었다면 InteractiveAuthenticationSuccessEvent.getGeneratedBy ()를 사용하는 아이디어가 작동하지 않습니다. getGeneratedBy는 Class 를 반환합니다. 이는 일반을 의미합니다. 따라서 런타임에 T가 RememberMeAuthenticationFilter인지 알 수 없습니다. 나에게 잘 돌아간 것 : InteractiveAuthenticationSuccessEvent.getAuthentication ()을 사용하십시오. Spring Security 4.2부터 @EventListener가 사용되었습니다. 이전 버전을 사용하는 경우 ApplicationListener 구현을 통해 다음을 수행하십시오.

    AuthenticationSuccessHandler를 사용하면 작동하지 않습니다. 다른 답변에서 언급했듯이, 스프링 보안 필터 체인은 무시 될 것입니다! 작동하는 것은 ApplicationListener를 사용하는 것입니다. 그러나 사용자를 기억하여 사용자가 인증 되었다면 InteractiveAuthenticationSuccessEvent.getGeneratedBy ()를 사용하는 아이디어가 작동하지 않습니다. getGeneratedBy는 Class 를 반환합니다. 이는 일반을 의미합니다. 따라서 런타임에 T가 RememberMeAuthenticationFilter인지 알 수 없습니다. 나에게 잘 돌아간 것 : InteractiveAuthenticationSuccessEvent.getAuthentication ()을 사용하십시오. Spring Security 4.2부터 @EventListener가 사용되었습니다. 이전 버전을 사용하는 경우 ApplicationListener 구현을 통해 다음을 수행하십시오.

    @Component
    public class AuthenticationApplicationListener {
    
        @EventListener
        public void handleInteractiveAuthenticationSuccess(InteractiveAuthenticationSuccessEvent event) {
            if (RememberMeAuthenticationToken.class.isAssignableFrom(event.getAuthentication().getClass())) {
                .... do some stuff
        }
      }
     }
    
  5. from https://stackoverflow.com/questions/11575860/remember-me-and-authentication-success-handler by cc-by-sa and MIT license