inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링 시큐리티

7) Remember Me 인증 필터 : RememberMeAuthenticationFilter

Remember-me .CookieTheftException Exception 문의

603

윤지상

작성한 질문수 14

0

안녕하세요 ^^. 

강의 잘듣고 있습니다. 

리멤버미 토큰 관련해서 질문이 있습니다. 

스프링 시큐리티 리멤버미 기능을 이용하고 있는데요, 토큰 저장소는 DB 에 저장을 해놓고요. 

하지만 스프링 application 을 restart 하게 되면 .CookieTheftException Exception 이 터집니다. 디버깅해보니, 이전에 저장되어 있던 Token value 와 새로 인입된 Token Value 가 일치하지 않더라고요.. 

테스트 순서는 아래와 같습니다.

1. 리멤버미를 이용한 로그인 후 로그인 성공

2. DB 및 쿠키 remember-me 확인 완료

3. Springboot app 재시작 

4. front 페이지 새로고침 

5. RememberMeTokenRepository  -> updateToken 메소드 호출 되면서 token value DB update

( 이때 페이지 새로고침했다고 토큰이 새로 발행되는게 맞나요? 토큰 expire 시간이 지나지도 않았는데)

6. 기존 token value 와 신규 token value 불일치로 인한 RememberMeTokenRepository -> removeUserTokens 메소드 호출되면서 token 삭제 

7. .CookieTheftException 예외 터짐 

일단 어플리케이션 재기동 이후 페이지 새로고침을 하는 순간 기존에 토큰 값이 아닌 새로운 값이 업데이트 되는데, 업데이트된 토큰 값 과 기존의 토큰 값이 불일치 하니 당연히 에러가 터지겠죠.. 

근데 왜 업데이트가 되는지 이해가 잘 안되네요.. 

혹시 어플리케이션 재기동하게되면 리멤버미 기능을 이용해서 이미 로그인되어 있는 유저들은 어떻게 처리해야 좋을까요?

혹시 몰라 아래 로그 달아드릴게요.. 

강의 너무 감사합니다. 

2021-07-16 16:10:09.061  INFO 18296 --- [nio-8080-exec-1] c.m.c.r.RememberMeTokenRepository        : remember-me token 획득
Hibernate: 
    select
        rememberme0_.series as series1_1_,
        rememberme0_.last_used as last_use2_1_,
        rememberme0_.token as token3_1_,
        rememberme0_.username as username4_1_ 
    from
        persistent_logins rememberme0_ 
    where
        rememberme0_.series=?
2021-07-16 16:10:09.262  INFO 18296 --- [nio-8080-exec-1] c.m.c.r.RememberMeTokenRepository        : remember-me token 획득 tokne oulEuy+jZS+XqpkJfzYwBw==
2021-07-16 16:10:09.297  INFO 18296 --- [nio-8080-exec-1] c.m.c.r.RememberMeTokenRepository        : remember-me token 업데이트 [ddCMgrk5Gm0hEqiH4LuvaQ==] [55vHBaBrKjGiA039ZzOH4w==]
Hibernate: 
    select
        rememberme0_.series as series1_1_,
        rememberme0_.last_used as last_use2_1_,
        rememberme0_.token as token3_1_,
        rememberme0_.username as username4_1_ 
    from
        persistent_logins rememberme0_ 
    where
        rememberme0_.series=?
Hibernate: 
    update
        persistent_logins 
    set
        last_used=?,
        token=?,
        username=? 
    where
        series=?
Hibernate: 
    select
        member0_.id as id1_18_,
        member0_.created_at as created_2_18_,
        member0_.updated_at as updated_3_18_,
        member0_.access_token as access_t4_18_,
        member0_.access_yn as access_y5_18_,
        member0_.account_type as account_6_18_,
        member0_.activated as activate7_18_,
        member0_.birth_date as birth_da8_18_,
        member0_.branch as branch9_18_,
        member0_.comment as comment10_18_,
        member0_.email_address as email_a11_18_,
        member0_.gender as gender12_18_,
        member0_.group_name as group_n13_18_,
        member0_.guide_count as guide_c14_18_,
        member0_.last_accessed_at as last_ac15_18_,
        member0_.name as name16_18_,
        member0_.password as passwor17_18_,
        member0_.phone as phone18_18_,
        member0_.point as point19_18_,
        member0_.position as positio20_18_,
        member0_.refresh_token as refresh21_18_ 
    from
        tb_member member0_ 
    where
        member0_.email_address=?
2021-07-16 16:10:09.403 ERROR 18296 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.lang.NullPointerException: null
	at org.springframework.security.authentication.AccountStatusUserDetailsChecker.check(AccountStatusUserDetailsChecker.java:41)
	at org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.autoLogin(AbstractRememberMeServices.java:137)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:104)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

2021-07-16 16:10:09.412  INFO 18296 --- [nio-8080-exec-1] c.m.c.r.RememberMeTokenRepository        : remember-me token 획득
Hibernate: 
    select
        rememberme0_.series as series1_1_,
        rememberme0_.last_used as last_use2_1_,
        rememberme0_.token as token3_1_,
        rememberme0_.username as username4_1_ 
    from
        persistent_logins rememberme0_ 
    where
        rememberme0_.series=?
2021-07-16 16:10:09.421  INFO 18296 --- [nio-8080-exec-1] c.m.c.r.RememberMeTokenRepository        : remember-me token 획득 tokne 55vHBaBrKjGiA039ZzOH4w==
2021-07-16 16:10:09.441  INFO 18296 --- [nio-8080-exec-1] c.m.c.r.RememberMeTokenRepository        : remember-me token 삭제 11
Hibernate: 
    select
        rememberme0_.series as series1_1_,
        rememberme0_.last_used as last_use2_1_,
        rememberme0_.token as token3_1_,
        rememberme0_.username as username4_1_ 
    from
        persistent_logins rememberme0_ 
    where
        rememberme0_.username=?
Hibernate: 
    delete 
    from
        persistent_logins 
    where
        series=?
2021-07-16 16:10:09.492 ERROR 18296 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] threw exception

org.springframework.security.web.authentication.rememberme.CookieTheftException: Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
	at org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices.processAutoLoginCookie(PersistentTokenBasedRememberMeServices.java:113)
	at org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.autoLogin(AbstractRememberMeServices.java:136)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:104)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
	at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:398)
	at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:257)
	at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:352)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

2021-07-16 16:10:09.493 ERROR 18296 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost]           : Exception Processing ErrorPage[errorCode=0, location=/error]

java spring-boot Spring Security

답변 1

0

정수원

제가 강의에서 리멤버 미 관련해서 DB 를 사용하는 방식은 몇가지 해결해야 할 이슈가 있어서 강의에서 제외했습니다.

일단 깃헙 소스 공유가 가능할까요?

DB 환경까지 갖추어 테스트하기가 쉽지는 않겠지만 직접 어플리케이션을 구동하지 않고서  답변을 드리기가 어려운 점이 있습니다.

시큐리티 공부 버전 질문

0

180

1

[해결 방법] MethodSecurityConfig.customMethodSecurityMetadataSource() 호출하지 않는 이슈

0

187

1

AbstractSecurityInterceptor.class.beforeInvocation()를 2번 실행하는 경우

0

181

1

강의 코드가 왜이렇게 뒤죽박죽인가요...

0

257

1

메인 페이지로 접속해도 login url로 리다이렉트가 되지 않습니다..

0

239

1

파라미터값이 넘어가지 않습니다 ....

0

376

1

security filterChain 설정 질문이 있습니다.

0

333

1

소스 부분 질문 드립니다.

0

210

2

섹션4 7번 강의 문제가 있는거 같네요.

0

345

2

파일이 수시로 이름이 바껴있네요 ㄷㄷ

0

307

1

HttpSessionSecurityContextRepository를 사용안하는 문제

0

559

2

error , exception 이 잘 안됩니다.

0

285

2

thymeleaf tag 질문합니다.

0

198

2

버전업하면서 deprecated된 것들이 너무많아요

0

479

1

spring security 패치 관련

0

439

1

모바일을 사용할때 토큰말고 세션

0

856

2

DB 연동한 인가 부분에 대한 질문입니다!

0

265

1

Ajax방식도 똑같이 Session방식을 사용하는건가요?

0

309

1

Config 파일 생성 시 질문이 있습니다.

0

228

1

강사님 몇일동안 구글 검색만 100개 했는데도 이유를 모르겠습니다..

1

435

2

403 에러 뜹니다.

0

814

2

login_proc의 존재에 대한 간략한 설명입니다

0

277

1

top.html에 로그인 링크를 만들어서 로그인을 해봤습니다

0

288

2

안녕하세요. DB에 저장될 때 이해 안 가는 값이 있어서 질문드립니다!

0

192

1