스프링 시큐리티 프레임워크는 Spring 서버에 필요한
인증
및인가
를 위해 많은 기능을 제공해준다.
Spring Security
프레임워크를 추가하기 위해서 build.gradle에 코드를 추가해야한다.
implementation 'org.springframework.boot:spring-boot-starter-security'
또한 Spring Security를 설정하기 위해서 Config 클래스를 하나 만들어서 설정해주어야 한다.
설정 파일을 WebSecurityConfig 라고 하겠다.
@Configuration
@EnableWebSecurity // Spring Security 를 지원하게 한다.
public class WebSecurityConfig {
// 이 역할은 어떤 url은 인가하고, 어떤 url은 인가하지 않으며 어떤 기능을 사용할지 옵션 설정해줌
// 이 역할을 이 메서드에서 한다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// CSRF 설정
http.csrf((csrf) -> csrf.disable()); // 사용하지 않겠다는 의미 -> CSRF란? 노션에 간단히 있으며 구글에 찾아보기로
http.authorizeHttpRequests((authorizedHttpRequests) ->
authorizedHttpRequests // 우리의 resources.static 폴더 안의 값들을 설정해줌 (모든 것을 허가한다 -> 인증처리하지 않고 허가해줌)
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()// resources 접근 허용 설정
.requestMatchers("/api/user/**").permitAll() // /api/user로 시작하는 모든 요청들은 허가해줌 (** 꼭!)
// .requestMatchers("/api/user/**").hasAnyRole() 이 안에 기능들은 되게 다양하다 -> 다양한 케이스를 손쉽게 처리할 수 있음
.anyRequest().authenticated() // 그 외 모든 요청은 인증처리 하겠다는 의미임
);
// 로그인 사용
http.formLogin(Customizer.withDefaults());
return http.build();
}
}
해당 WebSecurityConfig 클래스 파일 위에 먼저 수동으로 컨테이너에 등록하기 위해서 @Configuration 어노테이션을 사용한다.
그 아래에 @EnableWebSecurity 어노테이션을 사용하여 Spring Security를 지원하게 해준다.
그리고 직접 수동으로 빈을 등록하도록 한다.
해당 빈 등록할 메서드의 이름을 securityFilterChain으로 설정하여 SecurityFilterChain을 반환하는 메서드로 사용하자.
파라미터로 들어오는 값은 HttpSecurity 객체 타입이며 먼저 csrf 설정을 통해 사용하지 않을 것을 명시한다.
http.csrf((csrf) -> csrf.disable());
여기서 csrf란 무엇이냐 ?
CSRF(사이트 간 요청 위조, Cross-site request forgery)
공격자가 인증된 브라우저에 저장된 쿠키의 세션 정보를 활용하여 웹 서버에 사용자가 의도하지 않은 요청을 전달하는 것을 의미한다.
CSRF 설정이 되어있는 경우 html 에서 CSRF 토큰 값을 넘겨주어야 요청을 수신 가능하다.
쿠키 기반의 취약점을 이용한 공격 이기 때문에 REST 방식의 API 에서는 disable 가능하다.
POST 요청마다 처리해 주는 대신 CSRF protection 을 disable
해야한다.
http.csrf((csrf) -> csrf.disable());
그리고 나서 일단 http의 메서드를 보면
http.authorizeHttpRequests((authorizedHttpRequests) ->
authorizedHttpRequests
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.requestMatchers("/api/user/**").permitAll()
.anyRequest().authenticated()
);
여기서는 인증 처리를 통과해주느냐, 인증 처리를 하겠냐의 차이라고 보면 된다.
이전의 filter 처리 방식에서 우리는 특정 url이 들어오게 되면 처리를 할 것인지 doFilter로 통과할 것인지 작성한 것이 있다.
궁금하면 다시 보면 된다.
Spring Filter 처리 방식
여기서는 아주 간단하게 requestMatchers 메서드를 통해 간단하게 사용할 수 있다.
requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
resources.static 폴더 안에 있는 모든 요청들은 permitAll() 를 통해 인증처리를 하지 않고 넘겨준다는 것이다.
.requestMatchers("/api/user/**").permitAll()
/api/user 로 시작된 모든 url들은 인증처리 하지 않고 넘겨준다는 것이다.
이전의 filter 처리 방식에서 startWith() 메서드
를 사용해서 조금 길게 만든 코드를 간단하게 사용할 수 있다.
.anyRequest().authenticated()
그 외의 모든 요청은 인증처리한다는 의미이다.
http.formLogin(Customizer.withDefaults());
기존의 Spring Security가 제공하는 로그인 페이지를 default값으로 설정해준다.