의존성 추가
build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter-security")
...
}
Spring Security 의존성을 추가하고, 서버를 기동시키면 기본적인 최소 보안을 제공해준다.
제공되는 기본 보안을 정리하자면 아래와 같다.
1. 모든 요청은 인증이 되어야 접근이 가능하도록 변경됨
2. Form Login, httpBasic Login 인증 방식 지원
3. 기본 로그인 페이지 제공
4. 기본 사용자 계정을 한 개 제공
- 사용자명: user
- 비밀번호: 서버 기동 시 로그로 제공되는 랜덤 문자열
참고로 디폴트 유저의 name, password를 변경하고 싶다면 아래와 같이 프로퍼티를 추가해주면 된다.
spring:
security:
user:
name: custom
password: custom
그렇다면 Spring Security에서는 어떻게 이러한 기본 기능들을 제공해주는 것일까?
`WebSecurityConfigurerAdapter` 클래스에서 이를 설정해준다.
`WebSecurityConfigurerAdapter`를 간단하게 들여다보자.
사용자 정의 설정 구현 - WebSecurityConfigurerAdapter
package org.springframework.security.config.annotation.web.configuration;
@Order(100)
@Deprecated
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {
protected final HttpSecurity getHttp() throws Exception {
if (this.http != null) {
return this.http;
}
AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher();
this.localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
AuthenticationManager authenticationManager = authenticationManager();
this.authenticationBuilder.parentAuthenticationManager(authenticationManager);
Map<Class<?>, Object> sharedObjects = createSharedObjects();
this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects);
if (!this.disableDefaults) {
applyDefaultConfiguration(this.http);
ClassLoader classLoader = this.context.getClassLoader();
List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
.loadFactories(AbstractHttpConfigurer.class, classLoader);
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
this.http.apply(configurer);
}
}
configure(this.http);
return this.http;
}
...
protected void configure(HttpSecurity http) throws Exception {
this.logger.debug("Using default configure(HttpSecurity). "
+ "If subclassed this will potentially override subclass configure(HttpSecurity).");
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.formLogin();
http.httpBasic();
}
...
@Override
public void init(WebSecurity web) throws Exception {
HttpSecurity http = getHttp();
web.addSecurityFilterChainBuilder(http).postBuildAction(() -> {
FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
web.securityInterceptor(securityInterceptor);
});
}
}
Spring Security 의존성이 추가되면, 초기화 하는 과정에서 `getHttp()` 메서드를 호출하게 된다.
`getHttp()` 메서드는 `HttpSecurity` 객체를 반환하는 메서드이다. 여기서 마지막에 `configure()`메서드를 호출하는데, 여기서 기본 보안 설정이 적용된 것을 볼 수 있다.
기본적인 인증/인가 정책을 설정해 놓았는데, 이것 때문에 의존성을 추가하기만 해도 기본적인 보안이 적용되는 것이다.
그렇다면, 사용자가 커스텀하게 Security 설정을 구성하려면 어떻게 해야할까?
`WebSecurityConfigurerAdapter`추상클래스를 상속받는 설정 클래스를 만들고, 저 `configure()` 메서드를 오버라이딩 하여 빈으로 등록하면 될 것이다.
(현재 `WebSecurityConfigurerAdapter`를 상속 받는 것은 Deprecated 되어 있다, 상속 받아 오버라이딩 하는 방식이 아니라, 각각의 설정을 Bean 으로 등록하는 방식으로 변경되었다고 하는데, 이는 추후에 알아보도록 하자)
@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.authorizeRequests()
.anyRequest().authenticated()
http
.formLogin()
}
}
`SecurityConfig` 라는 클래스를 만들고 `WebSecurityConfigurerAdapter`를 상속 받아서 `configure()` 메서드를 오버라이딩 했다. 구현은 인증된 요청만 요청을 승인하도록 설정하고, `formLogin()`을 통해 폼으로 로그인하도록 설정을 해 놓은 모습이다.