[MSA Prepare] Spring Authorization User 추가하기

·2024년 5월 5일
0

MSA Prepare

목록 보기
13/21
post-thumbnail

기존방식

  • AuthorizationServerConfig.java
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(userDetails);
    }
  • 다음과 같이 InMemoryUserDetailsManager의 방식으로 사용자를 등록하였다.
  • DB를 추가하고 사용자를 추가하여 보자!

DB 설정

  • JPA와 H2 DB를 사용하였다.

dependencies

  • build.gradle
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	runtimeOnly 'com.h2database:h2'
}

설정하기

  • application.properties
# DATABASE
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:~/local
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

# JPA
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.defer-datasource-initialization=ture
spring.sql.init.mode=always
  • 추가적으로 data.sql을 사용하기 위한 설정도 하였다.

Authority

  • 권한을 저장하기 위한 Entity이다.
  • DTO를 사용하였다.
  • Authority.java
@Entity
public class Authority {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;
}

Customer

  • 사용자를 구성하는 방법에는 UserDetailsService를 구현하는 방식, 사용자를 UserDetails를 상속받아서 구현하는 방법이 있다.
  • UserDetails는 엔티티를 직접 인증에 사용할 수 있으므로 추가적인 변환 과정이 필요 없어 구현이 간단하다.
  • UserDetailsService는 엔티티와 Spring Security 사이의 의존성을 낮출 수 있다.

Entity

  • 마찬가지로 DTO를 사용하였다.
  • Customer.java
@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true)
    private String name;
    private String email;
    private String password;
    @OneToMany(mappedBy = "customer", fetch = FetchType.EAGER)
    private Set<Authority> authorities;
}

UserDetailsService

  • CustomerSecurityService.java
@Component
public class CustomerSecurityService implements UserDetailsService {

    private final CustomerRepository customerRepository;

    public CustomerSecurityService(CustomerRepository customerRepository) {
        this.customerRepository = customerRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Customer customer = customerRepository.findByName(username);
        if (customer != null) {
            return new User(customer.getName(), customer.getPassword(), getGrantedAuthorities(customer.getAuthorities()));
        }
        return null;
    }

    private List<GrantedAuthority> getGrantedAuthorities(Set<Authority> authorities) {
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (Authority authority : authorities) {
            grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_"+authority.getName()));
        }
        return grantedAuthorities;
    }
}
  • 다음과 같이 UserDetailsService을 상속받아서 작성한다.
  • loadUserByUsername를 반드시 작성해야함
  • getGrantedAuthorities는 권한을 반환하기 위한 함수이다.
profile
백엔드 개발자가 꿈인 컴공과

0개의 댓글

관련 채용 정보