모두의 마당 프로젝트에서 OAuth2 기반 네이버, 구글 소셜 로그인 구현 중, @AuthenticationPrincipal에 null값 들어오는 문제가 생겼다.
세션 기반 로그인 인증 방법을 사용했는데, 로그인한 유저가 세션에 저장되지 않는 오류같앴다.
참고
@AuthenticationPrincipal이란!
세션 정보 UserDetails에 접근할 수 있는 어노테이션
@GetMapping("")
@ApiOperation(value = "채팅방 리스트 조회 ", notes = "전체 채팅방 목록을 조회한다")
public String chatRoomList(Model model, @AuthenticationPrincipal SessionUser sessionUser) {
model.addAttribute("list",chatRoomService.findAllRooms());
log.info("채팅방 설정 =" + chatRoomService.findAllRooms());
// 세션에 저장된 로그인 정보를 모델에 추가
if (sessionUser != null) {
model.addAttribute("user", sessionUser.getAttributes());
}
log.info("유저 정보 =" + sessionUser.getAttributes());
return "roomlist";
}
SessionUser
)가 SecurityContext
에 제대로 저장되지 않았다.@AuthenticationPrincipal SessionUser sessionUser
어노테이션을 사용한 컨트롤러에서 sessionUser
객체가 null
로 주입되었다.해결 방법
-> 사용자 인증을 처리하는 곳을 다시 한번 살펴보자
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName, oAuth2User.getAttributes());
ChatUser chatUser = saveOrUpdate(attributes);
log.info("custon 부분 유저: "+chatUser);
log.info("custon 부분 유저2: "+httpSession.getId());
return new SessionUser(chatUser);
}
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName, oAuth2User.getAttributes());
ChatUser chatUser = saveOrUpdate(attributes);
log.info("custon 부분 유저: "+chatUser);
log.info("custon 부분 유저2: "+httpSession.getId());
SessionUser sessionUser = new SessionUser(chatUser);
Authentication authentication = new UsernamePasswordAuthenticationToken(sessionUser, null, sessionUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return sessionUser;
}
소셜 로그인에는 성공했는데, 다른 연동된 서비스를 구현할 때 문제가 생기면 먼저 인증/인가 처리하는 곳을 문제가 있는지 살펴보자!