LDAP를 활용해 사용자 인증하는 법을 배운다.
Lightweight Directory Access Protocol의 약자다.
Directory Service 제공자 접근에 사용하는 protocol이다. Directory Service는 DB랑 비슷하다고 볼 수 있는데, 차이점은 읽기나 특정 정보 검색에 특화되어 있고 쓰기를 허용하지 않는다는 것이다. 보통 조직의 회원 정보 혹은 사용자 정보를 저장하는데 활용된다.
LDAP 서버측에서는 저 정보를 Distinct Name (DN)이라는 identifier을 활용해가지고 저장을 하며, LDAP 사용자는 서버에다가 필요한 정보를 요청하는 형태로 운용이 된다.
좀 더 자세한 글은 삼성 SDS 측의 자료 확인
그러면 이게 보안이랑 무슨 관계냐, 사실 LDAP를 통해 특정 사용자의 credential이 유효한지를 확인하는 것이 가능하다. 그냥 LDAP server 측에서 사용자의 credential을 저장해놓으면 되기 때문이다. 지금부터 알아보도록 하자.
이건 이번 구현과는 크게 관련 없는 내용이긴 하나 참고하면 좋다.
@RestController
이 MVC의 controller을 Spring에게 알리는데 사용되긴 하지만, 동시에 Spring MVC에게 HTTP response body에다가 각 @GetMapping
의 결과물을 직접 넣으라는 것을 알리는 역할을 하기도 한다.
즉 따로 View, 및 해당 View를 위한 template이 존재하지 않을 때 사용해도 된다. 이 경우 web page에 그냥 HTTP response 내용물이 날것 그대로 튀어나오게 된다.
spring boot starter 중 security가 필요하며, spring-ldap-core, spring-security-ldap, unboundid-ldapsdk 등도 필요하다.
이를 통해 하려는 것은 Spring Security와 오픈 소스 LDAP 서버인 UnboundId를 집어넣기 위해서다.
SecurityFilterChain
람다꼴로 바꾸기 @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
return http.build();
}
formLogin
때문인데, deprecated가 원인이라고 나오며 검색을 해보면 람다 형식으로 작성을 하지 않아서 그렇다. 다음과 같이 수정하도록 하자. @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin(Customizer.withDefaults());
return http.build();
}
WebSecurityConfig
다. @Configuration
이 달려있는것을 보면 알 수 있듯이, 보안과 관련된 configuration에 관한 정보를 담은 bean을 생성하는 곳이다.먼저 securityFilterChain
을 보면 HttpSecurity
를 받고 SecurityFilterChain
을 반환한다.
SecurityFilterChain
은 서버 측에 온 request가 어떤 보안 '필터'들을 거쳐갈것인지를 명시하는 객체다. 즉 request가 올 때마다 다음과 같은 보안 검사 과정을 거친다는 것이다.
HttpSecurity
는 http request에 대한 보안 설정을 도와주는 class다. 특정 http request에 대해서 어떤 보안 절차를 거칠지를 설정할 때 사용된다. 원래는 이를 Spring Security 관련 xml에다가 직접 적어야 하는데 그게 뭣같을테니 얘로 대신 조작하라는 것을 의미. 각 method를 확인해보면
authorizeRequest
: request에 대한 authorization configuration을 시작할 때 사용되는 methodanyRequest
: 모든 http request에 대해 다음 보안 절차를 거치도록 설정fullyAuthenticated
: 온전한 authentication이 이루어져야만 통과and
: 그리고formLogin
: Spring에서 제공하는 form login 과정을 활용. 이때 개인 설정이 가능하나 여기서는 기본 설정을 활용했다. 관련 글즉 securityFilterChain
은 말 그대로 http request에 대한 보안 절차 과정을 setup하는 method다.
configure
method 관련이 method는 securityFilterChain
에서 만든 SecurityFilterChain
의 fullyAuthenticated
부분에서 사용할 authentication이 뭔지를 정하는 곳이다. 이때 injected된 authenticationManagerBuilder
의 instance, auth
를 활용한다.
각 method를 보면
ldapAuthentication
: ldap authentication을 활용하겠다는 것을 의미userDnPatterns
: 사용자 DN에 관한 pattern 설정. 여기서 {0}이 사용자 이름이 들어갈 곳이다. LDAP directory 상에서 사용자를 찾는데 사용할 DN pattern이다.groupSearchBase
: group search를 시작할 기반 DN을 지정하는 method.contextSource
: LDAP context source에 대한 configuration setup 시작url
: LDAP server URL 설정, LDAP operation을 위한 기반 DN 설정passwordCompare
: 사용자 비밀번호에 대한 확인 작업이 어떻게 이루어지는지 설정passwordEncoder
: password를 어떻게 암호화할지 설정. 날것으로 돌아다니면 안되서 설정.passwordAttribute
: LDAP상에서 암호화된 password를 어디에 보관하고 있는지를 표기. userPassword
에서 보관하고 있다고 표기중이다.데이터를 ldap형태로 제공한 resources에 보관한 다음에 서버를 실행하고 접속을 시도해보면 기본 로그인 화면이 나온다.
예시 resource에서는 ben
이라는 사용자만으로 제대로 접속이 가능하다는 점 유의
https://github.com/baekrang256/Backend-Practice/tree/main/SpringTutorial/authenticating-ldap