그 전까지는 스프링 시큐리티를 적용하기 위한 컴포넌트 구현하였음
스프링 시큐리티 관련 설정을 진행하는 대표적인 방법은 WebSecurityConfigureAdapter를 상속받는 Configuration 클래스를 구현하는 것
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
@Autowired
public SecurityConfiguration(JwtTokenProvider jwtTokenProvider){
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity.httpBasic().disable()
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/sign-api/sign-in", "/sign-api/sign-up",
"/sign-api/exception").permitAll()
.antMatchers(HttpMethod.GET, "/product/**").permitAll()
.antMatchers("**exception**").permitAll()
.anyRequest().hasRole("ADMIN")
.and()
.exceptionHandling().accessDeniedHandler(new CustomAccessDeniedHandler())
.and()
.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint())
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider),
UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity webSecurity){
webSecurity.ignoring().antMatchers("/v2/api-docs", "/swagger-resources/**",
"/swagger-ui.html", "/webjars/**", "/swagger/**", "/sign-api/exception");
}
}
configure()은 WebSecurity 파라미터를 받을때와, HttpSecurity 파라미터를 받는 경우 총 2가지
-> 대부분의 시큐리티 설정은 WebSecurity를 통해 진행
httpBasic().disable()
: UI를 사용하는 것을 기본값으로 가진 시큐리티 설정을 비활성화
csrf().disable()
: REST API에서는 CSRF(사이트 간 요청 위조) 보안이 필요 없기 때문에 비활성화 하는 로직, csrf() 메서드는 기본적으로 CSRF 토큰을 발급해서 클라이언트로부터 요청을 받을 때 마다 토큰을 검증하는 방식으로 동작, 브라우저 사용환경이 아니라면 비활성화 해도 크게 문제 X
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
: RESTAPI 기반 애플리케이션의 동작 방식 설정, 현재는 JWT 토큰으로 인증을 처리하며, 세션을 사용하지 않기에 STATELESS로 진행
authorizeRequest()
: 애플리케이션에 들어오는 요청에 대한 사용 권한 체크, 이후 antMatchers() 메서드
는 antPattern을 통해 권한 설정
"/sign-api/sign-in", "/sign-api/sign-up","/sign-api/exception" 경로에 대해서는 모두에게 허용
/product로 시작하는 경로의 GET요청은 모두 허용
exception 단어가 들어간 경로는 모든 허용
기타 요청은 인증된 권한을 가진 사용자에게 허용
exceptionHandling().accessDeniedHandler()
: 권한을 확인하는 과정에서 통과하지 못하는 예외가 있을 경우 예외 전달
exceptionHandling().authenticationEntryPoint()
: 인증 과정에서 예외가 발생하는 경우 예외 전달
위 두메서드는 CustomAccessDeniedHandler와 CustomAuthenticationEntryPoint로 예외 전달
스프링 시큐리티는 각각의 역할을 수행하는 필터들이 체인 형태로 구성돼 순서대로 동작
여기선 JWT로 인증하는 필터를 생성하였고, 필터의 등록은 HttpSecurity 설정에서 진행
addFilterBefore()
메서드를 통해 어느 필터 앞에 추가할지 설정할 수 있음
-> 위 코드에서는 스프링 시큐리티에서 인증을 처리하는 필터인 UsernamePasswordAuthenticationFilter 앞에 앞에서 생성한 JwtAuthenticationFilter를 추가하겠다는 의미
WebSecurity를 사용하는 configure() 메서드
-> WebSecurity는 HttpSecurity 앞단에 적용되며, 전체적으로 스프링 시큐리티 영향 밖
-> 즉 인증과 인가가 모두 적용되기 전에 동작하는 설정
-> 인증과 인가가 적용되지 않는 리소스 접근에 대해서만 사용
위 코드에서는 Swagger 관련된 경로에 대한 예외 처리를 수행하였음
-> 즉 인증과 인가를 무시하는 경로를 설정하는 것