Spring Security CustomUserDetails 구현하고 @AuthenticationPrincipal로 유저 정보 받아오기

Sadie·2023년 12월 4일
0

Spring And JPA

목록 보기
4/9

Spring Security에서 제공하는 인증 방법인 UserDetails를 사용하면 간단하게 사용자 인증을 할 수 있다
하지만 기능이 제한되어있기에 커스텀을 해서 유저 정보를 받아오게 할 것이다


CustomUserDetails

@Getter
public class CustomUserDetails implements UserDetails {
    private User user;
    private Map<String, Object> attribute;

    /* 일반 로그인 생성자 */
    public CustomUserDetails(User user) {
        this.user = user;
    }

    private GrantedAuthority getAuthority(Role role) {
        return new SimpleGrantedAuthority("ROLE_" + role);
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorityList = new ArrayList<>();

        switch (user.getRoles()) {
            case ADMIN : authorityList.add(getAuthority(Role.ADMIN));
            case MANAGER : authorityList.add(getAuthority(Role.MANAGER));
            case USER : authorityList.add(getAuthority(Role.USER));
        }

        return authorityList;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getNickname();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

}

UserDetails를 implements 해온다
현재 프로젝트에서 ROLE은 ADMIN, MANAGER, USER 3가지가 있다


CustomUserDetailsService

@Service
@RequiredArgsConstructor
public class UserDetailsServices implements UserDetailsService {

    private final UserRepository userRepository;

    // username이 DB에 존재하는지 확인
    // username -> email
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 시큐리티 세션에 유저 정보 저장
        return new CustomUserDetails(userRepository.findByEmail(username).orElseThrow(() ->
                new UsernameNotFoundException("사용자가 존재하지 않습니다.")));
    }

}

이름이 loadUserByUsername이지만(Override) email을 가져와서 확인한다


Controller

    // 게시물 추가
    @PostMapping("/add")
    public ResponseEntity save(@Valid @RequestBody PostingSaveDto postingSaveDto, @AuthenticationPrincipal CustomUserDetails customUserDetails, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            for(FieldError error : list) {
                return new ResponseEntity<>(error.getDefaultMessage(), HttpStatus.BAD_REQUEST);
            }
        }
        User user = customUserDetails.getUser();
        postingService.save(postingSaveDto, user);
        return new ResponseEntity(HttpStatus.CREATED);
    }

@AuthenticationPrincipal CustomUserDetails customUserDetails
로그인한 사용자의 정보를 불러와서 해당 글을 작성한 유저로 등록할때, 게시물 편집 등에서 해당 글이 본인이 쓴 글이 맞는지 확인할때 사용할 수 있다



참고

https://programmer93.tistory.com/68
https://goodteacher.tistory.com/597
https://cbn1218.tistory.com/11

0개의 댓글