728x90
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class BasicSecurity extends WebSecurityConfigurerAdapter {

    private final LoggingFilter loggingFilter;

    public BasicSecurity(LoggingFilter loggingFilter) {
        this.loggingFilter = loggingFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/token").authenticated()
            .antMatchers("/pin/unlock").permitAll()  // Explicitly allow /pin/unlock
            .anyRequest().permitAll()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();  // Disable CSRF for testing purposes

        // Add the logging filter before UsernamePasswordAuthenticationFilter
        http.addFilterBefore(loggingFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("....")
                .password("....")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }
}

 

서비스에서 POST를 정의하고 나서 일부 API에만 security 를 적용했을 경우, 다른 POST 도 영향을 받는다.

따라서 해당하는 POST들은 기본적으로 Spring Security 의 영향을 받기 때문에 별도로 permitAll을 해준다고 하더라도 모든 제약사항이 풀리진 않는다.

 

따라서 public 적으로 노출되는 POST Mapping 에 대해서는 csrf에 대해서 disable 해주는 전략이 필요하다. 

 

하지만 CSRF 를 disable 하지 않고 보안까지 지키려면 어떻게 해야할까?

 

const csrfToken = document.querySelector('meta[name="_csrf"]').getAttribute('content');
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').getAttribute('content');

fetch('http://localhost:8080/pin/unlock?uuid=o87a66240433494aa362ad88e69af9c5', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        [csrfHeader]: csrfToken
    },
    body: JSON.stringify({ /* your data */ })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

 

이렇게 던질때 csrf token 까지 냅다 던져주면 된다.

+ Recent posts