본문 바로가기
개발/Web

[Spring Boot] spring security - CSRF 적용 , +) ajax csrf 적용

by ynzu🤍 2021. 12. 7.
반응형

1. gradle 혹은 maven에 'spring-boot-starter-security' 추가

implementation 'org.springframework.boot:spring-boot-starter-security'
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.5.5</version>
</dependency>

Spring Security는 스프링 기반의 어플리케이션 보안을 담당하는 프레임워크로 Spring Security를 사용하면 보안처리를 간단하면서 강력하게 구현가능하다! 

 

2. XXXXApplication.java에 @EnableWebSecurity 선언

  • @EnableWebSecurity :Spring Security를 활성화
@EnableWebSecurity
@SpringBootApplication
@PropertySource(value = "classpath:test.yml", factory = YamlPropertySourceFactory.class)
public class TestApplication {

    public static void main(String[] args) {

        ConfigurableApplicationContext ctx = SpringApplication.run(TestApplication.class, args);
        
  	}
 }
  • XXXXApplication.java가 아니라 3번에서 작성한 WebSecurityConfig.java에 @EnableWebSecurity 등록 가능

 

3. WebSecurityConfigurerAdapter를 상속받는 class를 작성

  • @Configuration :해당 클래스를 Configuration으로 등록
  • 설정은 WebSecurityConfigurerAdapter 클래스를 상속받아 오버라이딩하는 방식으로 진행
  • /**
     * Web Security.
     * CSRF 방어 코드 적용
     */
    @Slf4j
    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        /**
         * CSRF 검사하지 않을 URL 목록
         */
        @Value("${test.security.csrf.exclude}")
        private String[] excludeUrl;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http
                    //CSRF 방어코드
                    .csrf().ignoringRequestMatchers(new CsrfIgnoringRequestMatcher(this.excludeUrl));
        }
    
        private static class CsrfIgnoringRequestMatcher implements RequestMatcher {
            //CSRF token 검증 하지 않을 HTTP METHOD
            private static final String[] ALLOWED_METHODS = new String[] {"GET", "OPTIONS"};
    
            //CSRF token 검증 하지 않을 url
            private final String[] allowedUrls;
    
            public CsrfIgnoringRequestMatcher(String[] allowedUrls) {
                this.allowedUrls = allowedUrls;
            }
    
            @Override
            public boolean matches(HttpServletRequest request) {
                String method = request.getMethod();
                for(String allowedMethod : ALLOWED_METHODS) {
                    if (allowedMethod.equalsIgnoreCase(method)) {
                        return true;
                    }
                }
    
                String uri = request.getRequestURI();
                uri = uri.replaceAll(request.getContextPath(), "");
                for (String allowedUrl : allowedUrls) {
                    if (uri.startsWith(allowedUrl)) {
                        return true;
                    }
                }
                return false;
            }
        }
    }
     

 

※주의 사항

1. ajax 통신을 할 때는 header의 csrf를 확인하므로 아래와 같이 header에 csrf를 세팅해줘야 함.

$.ajaxSetup({
  beforeSend: function(xhr) {
      xhr.setRequestHeader("AJAX", true);
      var csrfToken = $("input[name=_csrf]").val();
      xhr.setRequestHeader("X-CSRF-TOKEN", csrfToken);
  },

 

2. form 태그에 action이 있을 경우만 hidden csrf가 자동 생성됨 (없으면 csrf 안생김)

csrf hidden이 안 생긴다면 form태그에 action이 빠져있는지 확인해보자!

728x90
반응형

댓글