Spring Boot 3 & Security 6 시리즈: UserDetailsService, DTO 작성하기 (8편)

2023. 8. 7. 22:46·Spring/Spring Security
반응형
 
 

이번 포스트에서는 UserDetailsService, DTO 클래스를 작성해 보자

 

1. CustomUserDetailsService 코드 작성

1-1. 코드 작성하기

  • 이 코드는 Spring Security의 사용자 인증 정보를 관리하는 UserDetailsService 인터페이스를 직접 커스텀해서 구현하여 사용자의 인증 정보를 로드하는 서비스를 정의하는 클래스다.
@Slf4j
@RequiredArgsConstructor
@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String loginId) throws UsernameNotFoundException {
        // 1. userRepository로부터 loginId로 유저정보를 받아온다.
        User byLoginId = userRepository.findByLoginId(loginId)
                .orElseThrow(
                        () -> new ProfileApplicationException(ErrorCode.USER_NOT_FOUND)
                );

        // 2.user를 dto로 변환시켜준다.
        UserDto userDto = UserDto.fromEntity(byLoginId);

        // 3. 사용자 정보를 기반으로 SecurityUserDetailsDto 객체를 생성한다.
        return new SecurityUserDetailsDto(
                userDto,
                Collections.singleton(new SimpleGrantedAuthority(
                        userDto.roleType().toString()
                ))
        );
    }

}

1-2. 코드 분석

  • CustomUserDetailsService는 UserDetailsService 인터페이스를 구현한다. 이 인터페이스의 loadUserByUsername 메서드는 사용자의 이름(여기선 loginId)으로 사용자의 정보를 불러오는 역할을 한다. 코드에서는 우선 userRepository를 통해 loginId에 해당하는 사용자 정보를 데이터베이스에서 조회한다. 사용자가 존재하지 않으면 UsernameNotFoundException 대신 ProfileApplicationException을 발생시키고, 이는 ErrorCode.USER_NOT_FOUND를 사용해 구체적인 에러 상황을 설명한다.

  • 찾아낸 사용자 정보(User)는 DTO(Data Transfer Object)인 UserDto로 변환되어, 데이터를 캡슐화하고, 필요한 정보만을 가지는 형태로 만들어진다. 마지막으로, SecurityUserDetailsDto 객체가 생성되는데, 이 객체는 스프링 시큐리티에서 사용자의 상세 정보를 담는 역할을 한다. 사용자의 권한도 SimpleGrantedAuthority를 통해 설정되는데, 여기서는 UserDto의 roleType을 사용해서 권한을 설정한다. 이렇게 구현된 CustomUserDetailsService는 스프링 시큐리티에서 사용자 정보를 불러오고, 인증 및 권한 부여 과정에서 중요한 역할을 한다.

 

2. SecurityUserDetailsDto 구현

2-1. 코드 작성하기

  • SecurityUserDetailsDto 클래스는 스프링 시큐리티의 핵심 부분 중 하나로, 사용자의 인증 정보를 관리하는 데 사용되는 UserDetails 인터페이스를 구현한다. 이 클래스에서 주목해야 할 점은 어떻게 이 인터페이스의 메서드들이 사용자 정보를 다루는지에 대한 부분이다.
@Slf4j
@Getter
@AllArgsConstructor
public class SecurityUserDetailsDto implements UserDetails {

    @Delegate
    private UserDto userDto;
    private Collection<? extends GrantedAuthority> authorities;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Collections.singletonList(new SimpleGrantedAuthority(userDto.roleType().toString()));
    }

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

    @Override
    public String getUsername() {
        return userDto.loginId();
    }

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

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

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

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

2-2. 코드 분석

  • 이 코드에서 중요한 부분은 UserDto 필드와 authorities 필드다. UserDto는 사용자의 정보를 담고 있고, authorities는 해당 사용자에게 부여된 권한들을 나타낸다. 여기서 @Delegate 애노테이션의 사용은 특히 눈에 띄는데, 이를 통해 UserDto의 메서드들을 SecurityUserDetailsDto에서 바로 호출할 수 있게 해, 코드를 더욱 간결하게 만들어준다.

  • UserDetails 인터페이스를 구현한 메서드들을 보면, getAuthorities() 메서드는 사용자의 권한을 SimpleGrantedAuthority 객체로 변환하여 반환해 주는 역할을 한다. 이렇게 함으로써 스프링 시큐리티가 이해할 수 있는 형식으로 사용자의 권한을 제공하게 된다.

  • getPassword()와 getUsername() 메서드는 각각 사용자의 비밀번호와 로그인 ID를 반환해주는데, 이는 UserDto에서 직접 가져오는 방식으로 구현되어 있다. 이로써 로그인 과정에서 필요한 기본적인 사용자 정보를 제공하게 된다.

  • 마지막으로, isAccountNonExpired(), isAccountNonLocked(), isCredentialsNonExpired(), isEnabled()와 같은 메서드들은 계정의 상태를 나타내는데, 현재 예제에서는 모두 false로 설정되어 있어서, 실제 애플리케이션에서는 이 부분을 실제 상황에 맞게 조정해야 할 필요가 있다. 이 메서드들은 계정이 만료되었거나 잠겨 있거나, 그 밖의 상태를 나타내는 데 사용된다.

 

종합적으로, SecurityUserDetailsDto 클래스는 사용자의 인증 정보를 스프링 시큐리티가 이해할 수 있는 방식으로 제공하는 역할을 하고 있다.

 

 

다음 포스트에서 로그인과 메인페이지 컨트롤러를 생성하자👇🏻👇🏻

 

Spring Boot 3.1 & Spring Security 6: 로그인 & 메인 페이지 컨트롤러 (9편)

로그인 뷰를 보여주고 action을 실행시킬 로그인 컨트롤러와 메인페이지를 보여주게될 메인 컨트롤러를 작성한다. 1. @Controller - 로그인, 메인페이지 컨트롤러 1-1. LoginController 이 코드는 사용자의

curiousjinan.tistory.com

 

 

반응형

'Spring > Spring Security' 카테고리의 다른 글

Spring Boot 3.1 & Spring Security 6: 로그인 프로세스 및 JWT 토큰 동작 설명 (10편)  (0) 2023.08.08
Spring Boot 3.1 & Spring Security 6: 로그인 & 메인 페이지 컨트롤러 (9편)  (0) 2023.08.08
Spring Boot 3 & Security 6 시리즈: JWT Util 클래스 작성 (7편)  (0) 2023.08.07
Spring Boot 3 & Security 6 시리즈: JWT 검증 인터셉터 작성하기 (6편)  (0) 2023.08.07
Spring Boot 3 & Security 6 시리즈: AuthenticationProvider, 인증 핸들러 구현하기 (5편)  (0) 2023.08.07
'Spring/Spring Security' 카테고리의 다른 글
  • Spring Boot 3.1 & Spring Security 6: 로그인 프로세스 및 JWT 토큰 동작 설명 (10편)
  • Spring Boot 3.1 & Spring Security 6: 로그인 & 메인 페이지 컨트롤러 (9편)
  • Spring Boot 3 & Security 6 시리즈: JWT Util 클래스 작성 (7편)
  • Spring Boot 3 & Security 6 시리즈: JWT 검증 인터셉터 작성하기 (6편)
Stark97
Stark97
문의사항 또는 커피챗 요청은 링크드인 메신저를 보내주세요! : https://www.linkedin.com/in/writedev/
  • Stark97
    오늘도 개발중입니다
    Stark97
  • 전체
    오늘
    어제
    • 분류 전체보기 (248) N
      • 개발지식 (20)
        • 스레드(Thread) (8)
        • WEB, DB, GIT (3)
        • 디자인패턴 (8)
      • JAVA (21)
      • Spring (88)
        • Spring 기초 지식 (35)
        • Spring 설정 (6)
        • JPA (7)
        • Spring Security (17)
        • Spring에서 Java 활용하기 (8)
        • 테스트 코드 (15)
      • 아키텍처 (6)
      • MSA (15)
      • DDD (12) N
      • gRPC (9)
      • Apache Kafka (18)
      • DevOps (23)
        • nGrinder (4)
        • Docker (1)
        • k8s (1)
        • 테라폼(Terraform) (12)
      • AWS (32)
        • ECS, ECR (14)
        • EC2 (2)
        • CodePipeline, CICD (8)
        • SNS, SQS (5)
        • RDS (2)
      • notion&obsidian (3)
      • AI 탐험대 (1)
      • 팀 Pulse (0)
  • 링크

    • notion기록
    • 깃허브
    • 링크드인
  • hELLO· Designed By정상우.v4.10.0
Stark97
Spring Boot 3 & Security 6 시리즈: UserDetailsService, DTO 작성하기 (8편)
상단으로

티스토리툴바