처음에 로그인 계정을 추가하는 과정은 application.yaml에 아래와 같은 코드를 작성하여 추가할 수 있었다.
spring:
security:
user:
name: user
password: user123!
roles: USER
그리하여 또 다른 admin이라는 이름을 가진 계정을 추가해보려했다.
그냥 아~ application.yaml에 또 추가하면 되지 않을까 생각하였으나... 그것은 오산!! 먼저 UserDetailsServiceAutoConfiguration 클래스를 보자~!
UserDetailsServiceAutoConfiguration 클래스에 InMemoryUserDetailsManager() 메소드가 자동으로 Bean으로 등록 된다. 참고로 이 메소드에서 console창으로 password가 출력된다. 메소드를 살펴보면 매개변수로 받은 SecurityProperties에서 user객체를 받아온다.
그러면 또 SecurityProperties 클래스를 보자~!
@ConfigurationProperties
annotation의 prefix에 작성된 것은 application.yaml 설정 파일에서 우리가 작성했던 spring: security: 아래에 있는 설정 값들을 binding 하는 클래스 property class다.
이 클래스에는 user객체를 하나!! 생성해서 값을 넣어주고 있다. 그렇기에 application.yaml에서 user를 여러 개 둘 수 없는 것이다.
configure(AuthenticationManagerBuilder auth)
AuthenticationManagerBuilder를 이용하여 로그인 가능한 계정을 직접 추가할 수 있다.
@Configuration
@EnableWebSecurity
public class WebSecurityConfigure extends WebSecurityConfigurerAdapter {
/**
* 사용자 계정 추가
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("user123!").roles("USER")
.and()
.withUser("admin").password("admin123!").roles("ADMIN")
;
}
}
Spring security 5에서 DelegatingPasswordEncoder 클래스가 기본 PasswordEncoder로 사용된다.
그래서 그냥 저렇게 넣으면 매개변수로 받고 변환하는 과정에서 잘못 변환이 되고 실제 password와 일치하는지 검사할 때 다르다고 판단한다. 그리하여 password값 입력 앞에 {noop} 를 작성한다.
@Configuration
@EnableWebSecurity
public class WebSecurityConfigure extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}user123").roles("USER")
.and()
.withUser("admin").password("{noop}admin123").roles("ADMIN")
;
}
}