본문 바로가기
관리자

Programming-[Backend]/Spring Security

[스프링 시큐리티] 4. Logout, Rember me 필터

728x90
반응형

1. logout API

 

로그아웃 API의 사용법은 아래 코드에서 확인할 수 있다. 메서드별 설명은 주석으로 표기했다.

 

 

SecurityConfig.class

http
        .logout()
        .logoutUrl("/logout") //logout url 설정
        .logoutSuccessUrl("/login") //logout 시 이동할 url만 설정
        .addLogoutHandler(new LogoutHandler() { //logout이 성공했을 때 처리할 내용
            @Override
            public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
                HttpSession session = request.getSession();
                session.invalidate();
            }
        })
        .logoutSuccessHandler(new LogoutSuccessHandler() { //logout 시 이동할 url 및 더 많은 로직 구현 가능
            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                response.sendRedirect("/login"); //로그아웃 시 로그인 할 수 있는 페이지로 이동하도록 처리한다.
            }
        })
        .deleteCookies("remember-me");

 

 

기본적으로 AntPathRequestMatcher를 통하는 방식은 앞선 UsernamePasswordAuthenticationFilter와 같은 방식이다. 그리고 인증 정보를 받아와서 '세션 무효화, 인증 토큰 삭제, 쿠키 정보 삭제, 로그인 페이지로 리다이렉트' 를 하는 것이 기본이라고 이해하면 된다.

 

 


 

 

2. logout Filter

 

작성한 API의 LogoutHandler, LogoutSuccessHandler 부분에 break point를 걸고 로그인 후 http://localhost:8080/logout에 접속하여 로그아웃을 해보면, request.getSession 이후의 구문에서 CompositeLogoutHandler로 넘어가는 것을 확인할 수 있다.

 

CompositeLogoutHandler의 구성을 디버거의 this를 통해서 살펴보면 아래와 같이 CookieClearing, CsrfLogoutHandler, SecurityContextLogoutHandler, LogoutSuccessEventPublishingLogoutHandler 등으로 구성되어 있는 것을 볼 수 있다. 개략적으로는 이 정도만 이해하자.

 

 

 

 


 

3. Remember Me 인증 API

 

 

remember me 인증 기능은 세션이 만료되고 웹 브라우저가 종료된 이후에도 어플리케이션이 사용자를 기억하는 기능이다. 로그인 시 Remember-Me 쿠키를 서버에서 발급하여 사용자가 쿠키를 갖고 있다면 토큰 기반 인증을 사용하여 유효성을 검증하고 사용자를 로그인 시켜주는 방식이다.

 

 

rememberMeParameter 이름을 화면상의 이름과 일치시켜주어야한다.

 

http
                .rememberMe()
                .rememberMeParameter("remember") //기본값은 remember-me, 화면에서 체크박스 체크 시 넘겨주는 이름값을 설정해준다.
                .tokenValiditySeconds(3600) //기본값은 14일
//                .alwaysRemember(true) //remember me 기능이 활성화되지 않아도 항상 실행된다.
                .userDetailsService(userDetailsService); //user 계정을 조회하기 위한 service이며 객체를 @Autowired 해옴

 

설정 후 접속 시, SpringBoot에서 제공하는 Remember me on this computer 체크박스가 있는 것을 확인할 수 있다. 이 부분을 체크하면 기존 로그인때 JSESSIONID 라는 이름의 쿠키만 있는 것에 비해, 설정해둔 remember me 쿠키가 들어간다.

 

체크 해제 상태로 로그인 시 쿠키값

 

체크 시 remember-me 쿠기값이 추가된다.

 

일반 로그인 시, JSESSIONID라는 세션을 갖고 있으나, 개발자 도구에서 강제로 세션을 delete하여 세션이 만료된 상황을 가정해볼 수 있다. 이후 새로고침을 하면 다시 로그인 페이지로 리다이렉트 된다. 그러나 세션과 remember-me 쿠키를 모두 갖고 있는 상황에서는 세션이 만료되더라도 remember-me 쿠키에 의해서 다시 로그인이 되고 세션도 다시 받아오게 된다. 이를 아래 필터 부분에서 확인해보자.

 

 


 

4. Remember Me 필터

 

 

기본 흐름

다소 복잡해보일 수도 있으나, 결론적으로는 remember-me 쿠키가 있는지 검사하고 쿠키의 내용을 파싱하여 id, pasword 등의 값을 읽어들여서 인증을 처리하는 프로세스라고 보면 된다.

 

코드를 살펴보기 위해서, RememberMeAuthenticationFilter 파일에서 doFilter 부분에 line debugging을 한다. 디버깅을 할때는 세션은 삭제하고 remember-me 쿠키만 있는채로 새로고침을 해본다.

 

우선 if문 분기를 통해서 SecurityContextHolder에서 세션 객체인 Authentication이 있는지 확인한다. 지금 테스트는 세션이 없는 상황이므로 else 문으로 넘어가서 rememberMeAuth 객체를 확인한다.

 

rememberMeAuth 객체의 principal 내부에 username과 password가 bcrypt로 해싱되어 있다. 이 정보를 바탕으로 다시 새로운 Authentication을 생성하고, AuthenticationManager에서 관리하게 된다.

 

 

 

 


 

참조

 

1) 인프런 - 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 정수원님 강의

https://www.inflearn.com/course/%EC%BD%94%EC%96%B4-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0

728x90
반응형