2024-04-01
1. 예시 코드
아래와 같은 코드가 있다고 가정해 보자. 해당 코드의 결과는 항상 로그인이 되어 있든 로그인이 되어 있지 않던 로그아웃을 하던 "if (authentication.isAuthenticated()) log.info("인증됨")" 코드가 실행된다. 즉 authentication.isAuthenticated() 이 부분이 항상 true를 리턴한다. 그 이유는 무엇일까?
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.isAuthenticated())
log.info("인증됨")
else
log.info("인증안됨")
}
2. 원인
Spring Security에서는 기본적으로 인증(로그인)되지 않은 사용자도 'anonymousUser'로 인증되어 있다. 이는 사용자가 로그인되지 않았더라도 Spring Security의 보안 기능을 활용할 수 있도록 하는 것이며, 이런 방식으로 Spring Security는 항상 SecurityContextHolder에 인증 객체를 유지하여 보다 일관된 방식으로 보안을 관리할 수 있다. isAuthenticated() 메서드는 현재 사용자가 인증되어 있는지 여부를 확인하며, Spring Security는 사용자가 'anonymousUser'로 인증되어 있더라도 이를 인증된 상태로 간주한다. 따라서 isAuthenticated() 메서드는 항상 true를 반환하게 된다.
3. 코드 개선
그렇다면 익명 사용자가 아닌 실제 사용자가 로그인이 되어 있는지 안되어 있는지는 어떻게 체크하면 좋을까? 해당 코드에 한단계를 더 추가하면 된다. 바로 해당 유저가 익명 유저인지 여부를 확인하면 되는 것이다. 아래의 코드를 보자. 해당 유저가 AnonymousAuthenticationToken를 가진 유저인지 여부를 확인하거나 아니면 해당 유저의 이름이 'anonymousUser' 인지 체크를 해주면 된다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//authentication.getName().equals("anonymousUser")
if (authentication != null && authentication.isAuthenticated() && !(authentication instanceof AnonymousAuthenticationToken)) {
return true;
} else {
return false;
}
3. 출처
메인 이미지 출처 : 사진: Unsplash의Nick Da Fonseca