[Spring-Security] 계정 정지 기능 구현 - 2
in Spring on Spring-Security
계정잠금기능 설정하기 - 2
이번에는 계정 정지를 넘어 실시간으로 유저를 로그아웃 시키는 방법을 알아보자
1편에서 이어지는 내용이므로, 1편의 내용은 아래링크를 참조하세요.
클릭하시면 1편으로 이동합니다.
***
사용된 개념은 다음과 같다
- SpringSecurity에서 사용자의 요청을 처리할때 세션에 인증정보가 있으면 해당 인증정보를 Security Context에 저장함
- 인증정보가 저장되어있는 객체는 SessionRegistry이며, getAllPrincipals() 메소드로 현재 인증된 모든 사용자 세션을 가져올수있음. 3.반환된 객체를 로그인에 사용한 UserDetails 혹은 User 객체를 상속한 객체로 캐스팅 후 루프를 돌리며 특정 유저의 Unique필드와 캐스팅한 객체의 같은 필드를 대조한다.
- 대조하다 정지시킬 유저의 Unique필드와 같을때 SessionRegistry의 getAllSessions()로 해당 유저의 객체로 생성된 모든 세션을 가져옴.
- 반환받은 객체는 SessionInfomation이란 객체의 컬렉션인데, 이 역시 루프를 돌려서 정지시킬 계정의 특정 unique값과 대조하여 해당하는 세션을 만료시켜 로그아웃 시키는 기능을 이용함.
우선, SessionRegistry를 우리가 주입받아 사용할 수 있도록 Security설정파일에 SessionRegistry 빈을 등록한뒤, SessionManagement에 해당 빈을 등록시키고, 세션이 만료되었을경우 스프링 시큐리티가 이를 감지하도록 이벤트 리스너도 빈으로 등록해둔다.> ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ... 생략 @Override protected void configure(HttpSecurity http) throws Exception{ ... 생략 http.sessionManagement.sessionRegistry(sessionRegistry()); } // SessionRegistry 빈등록 및 SessionManagement SessionManagementFilter에 등록 @Bean public SessionRegistry sessionRegistry(){ return new SessionRegistryImpl(); } // 세션 만료시 SpringSecurity가 이를 감지하도록 이벤트 리스너 설정 @Bean public static ServletListenerRegistrationBean
```
@Service
@RequireArgsConstructor
@Transactional
public class BlockUserService{
private final MemberRepository memberRepository;
private final SessionRegistry sessionRegistry;
public void blockUser(Long memberId){
Member findMember = memberRepository.findById(memberId).orElseThrow();
findMember.setLocked(true); // 유저 계정 잠그기
// 모든 세션에서 인증된 객체를 가져와서 UserDetails 혹은 User객체 상속한 로그인용 DTO객체로 변환
List