[SpringSecurity] Principle 객체를 사용하여 현재 로그인한 사용자 정보 얻기

최가희·2022년 8월 6일
0

SpringBoot

목록 보기
10/13
post-thumbnail

게시판의 질문 또는 답변에 작성자를 표시하는 기능을 추가하려고 한다. Question, Answer 엔티티에 author 속성이 추가되었다고 가정한 상태로 진행한다.

스프링 시큐리티에서 제공하는 Principle 객체를 사용하면 현재 로그인한 사용자에 대한 정보를 알 수 있다.


답변에 작성자 저장하기

답변을 등록하는 createAnswer 메서드에 Principle 객체를 매개변수로 지정한다.
principal.getName()을 호출하면 현재 로그인한 사용자의 username(사용자 id)을 알 수 있다.
AnswerController.java

(... 생략 ...)
import java.security.Principal;
(... 생략 ...)
public class AnswerController {

    (... 생략 ...)

	@PreAuthorize("isAuthenticated()")
    @PostMapping("/create/{id}")
    public String createAnswer(Model model, @PathVariable("id") Integer id, 
            @Valid AnswerForm answerForm, BindingResult bindingResult, Principal principal) {
        (... 생략 ...)
    }
}

@PreAuthorize("isAuthenticated()")
이 어노테이션이 붙은 메서드를 로그인이 필요한 메서드를 의미하며, 로그아웃 상태에서 호출될 경우 로그인 페이지로 이동된다.

SecurityConfig.java

(... 생략 ...)
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
(... 생략 ...)

@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    (... 생략 ...)
}

@EnableGlobalMethodSecurity(prePostEnabled = true)
AnswerController에서 로그인 여부를 판별하기 위해 사용한 @PreAuthorize 어노테이션을 사용하기 위해 반드시 필요하다.

UserService.java

(... 생략 ...)
import java.util.Optional;
import com.mysite.sbb.DataNotFoundException;
(... 생략 ...)
@Service
public class UserService {

    (... 생략 ...)

    public SiteUser getUser(String username) {
        Optional<SiteUser> siteUser = this.userRepository.findByusername(username);
        if (siteUser.isPresent()) {
            return siteUser.get();
        } else {
            throw new DataNotFoundException("siteuser not found");
        }
    }
}

AnswerService.java

(... 생략 ...)
import com.mysite.sbb.user.SiteUser;
(... 생략 ...)
public class AnswerService {

    (... 생략 ...)

    public Answer create(Question question, String content, SiteUser author) {
        Answer answer = new Answer();
        answer.setContent(content);
        answer.setCreateDate(LocalDateTime.now());
        answer.setQuestion(question);
        answer.setAuthor(author);
        this.answerRepository.save(answer);
        return answer;
    }
}

AnswerController.java
principal 객체를 통해 사용자명을 얻은 후, 사용자명을 통해 SiteUser 객체를 얻어서 답변을 등록하는 AnswerService의 create 메서드에 전달하여 답변을 저장한다.

(... 생략 ...)
import com.mysite.sbb.user.SiteUser;
import com.mysite.sbb.user.UserService;
(... 생략 ...)
public class AnswerController {

    private final QuestionService questionService;
    private final AnswerService answerService;
    private final UserService userService; // 추가된 부분

    @PostMapping("/create/{id}")
    public String createAnswer(Model model, @PathVariable("id") Integer id, 
            @Valid AnswerForm answerForm, BindingResult bindingResult, Principal principal) {
        Question question = this.questionService.getQuestion(id);
        SiteUser siteUser = this.userService.getUser(principal.getName()); // 추가된 부분
        if (bindingResult.hasErrors()) {
            model.addAttribute("question", question);
            return "question_detail";
        }
        this.answerService.create(question, answerForm.getContent(), siteUser); // 수정된 부분
        return String.format("redirect:/question/detail/%s", id);
    }
}

참고

점프 투 스프링

0개의 댓글