Spring Security, H2 연동했을때 문제해결

2017-08-12 19:34

잘쓰던 H2 데이터베이스가 갑자기 Spring boot + Spring Security와 연동하니 작동을 하지 않았다.

Spring Security 에서 H2 데이터 베이스 콘솔에 접근을 차단 한 것이다.

이 문제를 해결하기 위해서

다음과 같은 Spring Security 설정을 진행하였다.

  1. H2 데이터베이스 콘솔 url("/h2-console/*") 요청에 대한 허용
  2. CSRF 중지
  3. X-Frame-Options in Spring Security 중지

코드로 보자면

http.authorizeRequests().antMatchers("/h2-console/*").permitAll()

http.csrf().disable()

http.headers().frameOptions().disable()

이러한 문제때문에 고생하고 있을 분들을 위해 정보 공유차 이 글을 쓴다.

3개의 의견 from SLiPP

2017-08-18 12:47

.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("!/h2-console/**")) .and().headers().addHeaderWriter(new StaticHeadersWriter("X-Content-Security-Policy","script-src 'self'")).frameOptions().disable()

저 같은 경우는 이렇게 쓰고 있네요. csrf를 모두 꺼버리는 부분이 불편하신 분은, 위 코드의 첫줄처럼 해보시는 것도 좋을 것 같습니다.

2017-08-29 15:33

저같은 경우에 h2-console이 결국 로컬개발에서만 사용될거라서 로컬모드와 그외 모드로 나눠서 시큐리티 설정이 먹히도록 작업하고 있습니다.

    private final Environment env;

    public SecurityConfig(Filter ssoFilter, Environment env) {
        this.ssoFilter = ssoFilter;
        this.env = env;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // h2 console이 csrf 설정이 안먹히기 때문에 security 설정을 배포 환경에 따라 분리
        if(isLocalMode()) {
            setLocalMode(http);
        } else {
            setRealMode(http);
        }
    }

    private boolean isLocalMode() {
        String profile = env.getActiveProfiles().length > 0? env.getActiveProfiles()[0] : "local";
        return profile.equals("local");
    }

    private void setLocalMode(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/", "/me", "/h2-console/**", "/login/**", "/js/**", "/css/**", "/image/**", "/fonts/**", "/favicon.ico").permitAll()
                .and().headers().frameOptions().sameOrigin()
                .and().csrf().disable()
                ;
    }

    private void setRealMode(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
                .authorizeRequests()

                .and().csrf().csrfTokenRepository(csrfTokenRepository())
                .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
                ;
    }
의견 추가하기