티스토리 뷰

Spring Security 에서 현재 인증된(로그인한) 사용자의 정보를 가져오는 방법 에 대해 살펴볼 것 입니다. 스프링의 다양한 메카니즘을 통해 현재 로그인 중인 사용자의 정보를 가져올 수 있는데, 대표적인 몇 가지를 살펴보겠습니다.

1. Bean 에서 사용자 정보 얻기

가장 간단한 방법은 전역에 선언된 SecurityContextHolder을 이용하여 가져오는 방법입니다.

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = (UserDetails)principal;

String username = principal.getUsername();
String password = principal.getPassword();

2. Controller 에서 사용자 정보 얻기

@Controller로 선언된 bean 객체에서는 메서드 인자로 Principal 객체에 직접 접근할 수 있는 추가적인 옵션이 있습니다.

@Controller
public class SecurityController {

    @GetMapping("/username")
    @ResponseBody
    public String currentUserName(Principal principal) {
        return principal.getName();
    }
}

principal 객체 뿐만 아니라 authentication 토큰 또한 사용할 수 있습니다.

@Controller
public class SecurityController {

    @GetMapping("/username")
    @ResponseBody
    public String currentUserName(Authentication authentication) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();

        return userDetails.getUsername();
    }
}

3. @AuthenticationPrincipal

Spring Security 3.2 부터는 annotation을 이용하여 현재 로그인한 사용자 객체를 인자에 주입할 수 있습니다.

만약 UserDetails 를 구현한 CustomUser 클래스가 있고, UserDetailsService 구현체에서 CustomUser 객체를 반환한다고 가정합시다. (가장 흔한 케이스)

@Data
public class CustomUser implements UserDetails {
    // ...
}
@Service
public class UserSerivce implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        CustomUser customUser = null;
        // ... DB 등을 통해 사용자 정보를 셋팅

        return customUser;
    }

다음과 같이 @AuthenticationPrincipal를 이용하여 CustomUser 객체를 인자에 넘겨줄 수 있습니다.

@Controller
public class SecurityController {

    @GetMapping("/messages/inbox")
    public ModelAndView currentUserName(@AuthenticationPrincipal CustomUser customUser) {
        String username = customUser.getUsername();

        // .. find messages for this user and return them ...
    }
}


댓글