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 까지 냅다 던져주면 된다.
'Java' 카테고리의 다른 글
MyBatisPagingItemReader with ExecutorType.Batch (0) | 2024.07.10 |
---|---|
[MyBatis] Page with MyBatis (0) | 2024.07.01 |
[method] java stream mapToObj (0) | 2024.05.07 |
[Spring Batch] multiple nodes with MySQL 8.0.33 (0) | 2024.05.03 |
자바 어플리케이션 inputstream 주의사항 (1) | 2024.04.18 |