기존방식
- AuthorizationServerConfig.java
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
- 다음과 같이 InMemoryUserDetailsManager의 방식으로 사용자를 등록하였다.
- DB를 추가하고 사용자를 추가하여 보자!
DB 설정
dependencies
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
}
설정하기
# 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는 권한을 반환하기 위한 함수이다.