Spring boot web, security의존성을 설정하고 프로젝트를 시작하면 아래와 같이
Using generated security password: d09c0129-c06d-4ebe-9a94-fe48cc494b74
새 암호가 생성된다. Http basic 인증으로 endpoint를 호출하려면 이 암호를 이용하여 호출해야한다
Authentication Filter는 인증 요청을 Authentication Manager에 위임후 Security Context구성
Authentication Manager는 Authentication Provider를 이용해 인증 처리
Authentication Provider는 인증 과정 구현
구현 과정중 필요한 provider를 이용
인증후 Security Context에 데이터 유지
기본 설정
User DetailService : 사용자에 관한 세부 정보를 등록하는 Bean이다.
PasswordEncoder : 암호를 인코딩한다, 암호가 서로 일치하는지 검증한다
HTTPS 설정
openssl을 이용한 자체 서명 인증서 생성
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
openssl pkcs12 -export -in certificate.pem -inkey key.pem -out certificate.p12
---
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:korea
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:junnyland
Organizational Unit Name (eg, section) []:junny
Common Name (e.g. server FQDN or YOUR name) []:security
Email Address []:junnyland@test.com
Enter Export Password:
Verifying - Enter Export Password:
Http Basic 인증은 대부분의 어플리케이션에 적합하지 않다. 마찬가지로 어플리케이션의 모든 엔드포인트를 보호할 필요는 없으며, 보안이 필요한 엔드포인트에 다른 권한 규칙을 선택해야 할 수도있다.
WebSecurityConfigurerAdapter클래스를 확장 하여 규칙을 정한다.
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain = http
.httpBasic{ }
.authorizeHttpRequests { it.anyRequest().authenticated() }
// 모든 요청에 인증 필요
.build()
다른 방법으로는 UserDetailService를 사용한 방법이 있다.
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain = http
.authenticationManager(authenticationManager(AuthenticationManagerBuilder(objectPostProcessor)))
.build()
fun userDetailsService(): UserDetailsService = InMemoryUserDetailsManager()
.also { it.createUser(User.withUsername("junnyland").password("1234").roles("USER").build()) }
fun authenticationManager(auth: AuthenticationManagerBuilder): AuthenticationManager = auth
.also {it.userDetailsService<UserDetailsService>(userDetailsService())
.passwordEncoder(passwordEncoder()) }
.build()
AuthenticationProvider
Spring Security를 구성하는 구성요소에 작업을 위임하는 옵션을 적용할수 있게한다.
@Component
class CustomAuthenticationProvider: AuthenticationProvider {
override fun authenticate(authentication: Authentication): Authentication {
val username = authentication.name
val password = authentication.credentials.toString()
if (username == "junnyland" && password == "1234") {
return UsernamePasswordAuthenticationToken(username, password, emptyList())
}
throw BadCredentialsException("Authentication failed for user $username")
}
override fun supports(authentication: Class<*>): Boolean {
return UsernamePasswordAuthenticationToken::class.java.isAssignableFrom(authentication)
}
}
위는 처음 등록햇던 UserDetailService를 대체한다
프로젝트에 여러 구성 클래스 이용
위처럼 하나의 구성클래스만 사용하는 방법도 있지만, 각 구성클래스의 책임을 분리하는 것이 좋습니다.
@Configuration
class UserManagementConfig {
@Bean
fun userDetailsService(): UserDetailsService = InMemoryUserDetailsManager()
.also { it.createUser(withUsername("junnyland").password("1234").roles("USER").build()) }
@Bean
fun passwordEncoder(): PasswordEncoder = createDelegatingPasswordEncoder()
}