728x90
반응형

 

Spring Boot security 를 구현하여 로그인, 로그아웃을 처리하고 있습니다.

 

고객이 로그아웃을 할때에 기록을 남겨 달라는 고객사의 요청이 있었습니다.

 

Security 를 사용할때 편하게 Session이 소멸시점을 체크할 수 있는 방법을 알아보겠습니다.

 

 

 

 

Security 설정에서 logout 을 세션을 초기화하는 코드를 작성합니다.

.and().logout()
      .logoutUrl("/logout")
      .logoutSuccessUrl("/login")  // 로그아웃 성공시 메인 고정
      .invalidateHttpSession(true)    // session invalidate
      .deleteCookies("JSESSIONID")	// cookie
      .permitAll()

 

 

 

Member Entity 입니다.

@Data
@Entity
@Table(name = "테이블")   // 회원 테이블
public class Member implements UserDetails {

	...
    
    /************************************
        UserDetails Override functions
     ************************************/
    /**
     * 사용자에게 부여된 권한
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
    	Set<GrantedAuthority> roles = new HashSet<>();
		role.forEach(e -> {
    		roles.add(new SimpleGrantedAuthority(e.getValue()));
    	});
    	return roles;
    }

    /**
     * 사용자 인증에 사용된 암호
     */
    @Override
    public String getPassword() {
        return memberPw;
    }

    /**
     * 사용자 인증에 사용된 이름
     */
    @Override
    public String getUsername() {
        return memberId;
    }

    /**
     * 사용자 계정 만료 여부
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    /**
     * 사용자가 잠김 여부
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    /**
     * 사용자의 자격증명(암호)이 만료 여부
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    /**
     * 사용자의 사용가능여부
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

 

 

 

 

 

session 이 소멸하게 되면 아래의 listener 로 진입합니다.

 

SessionDestroyedEvent를 implemets 하면 security 로그인했던 사용자 정보를 담아두고 있습니다.

 

사용자는 UserDetails 를 상속받거나 User를 구현했다면 정보를 조회할 수 있습니다.

 

이때는 request 가 없기 때문에 필요한 정보는 미리 UserDetails 에 넣어둔 뒤 소멸되는 시점에 기록을 남기면 됩니다.

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.session.SessionDestroyedEvent;
import org.springframework.stereotype.Component;

import com.kcknock.primary.domain.Member;
import com.kcknock.primary.domain.MemberState;
import com.kcknock.primary.repository.MemberStateRepository;

/**
 * sessionDestroyed 요청시
 * @author gigas
 */
@Component
public class SessionDestroyListener implements ApplicationListener<SessionDestroyedEvent>{

	@Autowired
	private MemberStateRepository memberStateRepository;
	
	@Override
	public void onApplicationEvent(SessionDestroyedEvent event) {
		List<SecurityContext> securityContexts = event.getSecurityContexts();

        for (SecurityContext securityContext : securityContexts) {
        	
        	Member member = (Member)securityContext.getAuthentication().getPrincipal();
        	
        	MemberState memberState = new MemberState();
        	memberState.setMemberId(member.getMemberId());
        	memberState.setType("로그아웃");
//        	memberState.setDevice("");
//        	memberState.setIpAddr("");
//        	memberState.setOs("");
        	
        	memberStateRepository.save(memberState);
        }
	}
}

 

 

 

 

소멸시점을 check 하는것처럼 생성시점도 아래와 같이 확인할 수 있습니다.

@Component
public class SessionCreateListener implements ApplicationListener<SessionCreationEvent> {

	@Override
	public void onApplicationEvent(SessionCreationEvent event) {
    
    }
}

 

 

 

 

이와같은 코드를 작성하면서 세션이 초기화되면 자동로그아웃을 구현해야겠다는 생각이 들었습니다.

 

하지만 찾아본 결과로는 해당 session 을 처리하는 곳에선 request 정보가 없기때문에 처리가 어렵다는 글들이 많던데..

 

최대한 '자동로그아웃' 기능을 찾아서 글로 남겨보도록 하겠습니다.

728x90
반응형

+ Recent posts