스터디-Spring

[스프링 시큐리티] 스프링 시큐리티 커스터마이징 - JPA 연동

일태우 2022. 1. 7. 16:39

JPA + H2 추가

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>

 

Account Entity

@Entity
public class Account {


    @Id @GeneratedValue
    private Integer id;

    @Column(unique = true)
    private String username;

    private String password;

    private String role;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public void encodePassword() {
        this.password = "{noop}" + this.password;
    }
}

AccountRepository

public interface AccountRepository extends JpaRepository<Account, Integer> {
    Account findByUsername(String username);
}

AccountService

/**
 * SecurityConfig에
 * protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 * auth.userDetailsService(accountService);
 * 로 등록 해도 되지만 UserDetailsService의 구현체가 bean으로 등록되어 있어도 사용가능함
 */
@Service
public class AccountService implements UserDetailsService {

    @Autowired
    AccountRepository accountRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Account account = accountRepository.findByUsername(username);
        if (account == null) {
            throw new UsernameNotFoundException(username);
        }

        return User.builder()
                .username(account.getUsername())
                .password(account.getPassword())
                .roles(account.getRole())
                .build();
    }

    public Account createNew(Account account) {
        account.encodePassword();
        return accountRepository.save(account);
    }
}
  • SpringSecurity의 Password 기본 정책은 Password은 인코딩 되어 있어야하고 어느 인코딩 방식인지 {xxxcrypt}1234 처럼 포맷으로 작성되어야한다

SecurityConfig

  • inmemory user 추가부분을 삭제한다

 

해결한 문제

  • 패스워드가 코드에 노출되지 않는다
  • DB를 사용하여 계정관리가 가능하다
  • 여러 사용자를 role에 맞게 등록 가능하다

새로운 문제

  • 패스워드에 기본 포맷 {noop}1234 와 같은 형식을 사용하지 않을 수 있을까
  • 테스트가 너무 불편하다