유저에 따라 권한이 나눠지는 페이지를 구현하려면 인증과 인가에 대한 고민을 해야함
Http 프로토콜은 Stateless한 특징을 지니고 있기 때문에 이를 해결할 수 있는 Session 기반과 Token 기반의 방식 중 선택
해당 내용은 다음 페이지에서 확인
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private UserRepository userRepository;
@Autowired
private CorsConfig corsConfig;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.addFilterBefore(new JwtExceptionFilter(), JwtAuthorizationFilter.class);
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.formLogin().disable()
.httpBasic().disable()
.apply(new MyCustomDsl())
.and()
.authorizeRequests()
.antMatchers("/user/**")
.access("hasRole('ROLE_USER') or hasRole('ROLE_REGISTER') or hasRole('ROLE_ADMIN')")
.antMatchers("/register/**")
.access("hasRole('ROLE_REGISTER') or hasRole('ROLE_ADMIN')")
.antMatchers("/admin/**")
.access("hasRole('ROLE_ADMIN')")
.anyRequest().permitAll();
return http.build();
}
public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> {
@Override
public void configure(HttpSecurity http) throws Exception {
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
http
.addFilter(corsConfig.corsFilter())
.addFilter(new JwtAuthenticationFilter(authenticationManager))
.addFilter(new JwtAuthorizationFilter(authenticationManager, userRepository));
}
}
}
위의 FilterChain은 DispatherServlet에 도달하기 전에 거치는 필터
addFilterBefore() : 원하는 필터 앞에 설정하고 싶은 필터를 넣는다.
코드에서 보이는 필터는 4. JWT 만료처리 페이지를 참고
csrf().disable() : SecurityFilter 는 기본적으로 CSRF를 enable 시킨다.
해당 프로젝트는 7. CSRF 공격 페이지와 같은 방법으로 CSRF에 방어하므로 disable로 설정
formLogin().disable() : SecurityFilter 는 기본으로 LoginForm이 존재한다. /login에 들어가게 되면 SecurityFilter에서 만들어둔 form으로 들어가므로 해당 기능을 사용하지 않는다는 코드
httpBasic().disable() : 해당 방식은 Http Header에 Authorization : **{ID, PW}**와 같이 정보를 담아 보내는데 한눈에 봐도 너무나 위험한 방식이기에 disable 한다.
해당 프로젝트에선 Bearer 방식을 사용했는데 Authorization 에 토큰을 담으므로 노출 시 위험부담이 Basic 방식에 비해 적음