All my GET
requests works fine with authorized access but, all my POST
requests are returned with 401 unauthorized access and I am using Basic authorization with username and password, I guess the problem is emerging from CSRF token but I have disabled and nothing happens.
Below is my SecurityConfig
class
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
//.cors(Customizer.withDefaults())
.csrf((csrf) -> csrf.disable())
.authorizeHttpRequests((authz) -> authz
.requestMatchers(HttpMethod.GET, "/api/**").permitAll()
//.requestMatchers(HttpMethod.POST, "/api/**").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
@Bean
public UserDetailsService users() {
// The builder will ensure the passwords are encoded before saving in memory
//User.UserBuilder users = User.withDefaultPasswordEncoder();
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("pass"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
and this is my controller
@PreAuthorize("hasRole(ADMIN)")
@PostMapping
public ResponseEntity<PostDto> createPost(@Valid @RequestBody PostDto postDto) {
return new ResponseEntity<>(postService.createPost(postDto), HttpStatus.CREATED);
}
and these are my logs
2023-09-10T23:55:35.850+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/api/posts
2023-09-10T23:55:35.850+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
2023-09-10T23:55:35.851+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : Securing POST /error
2023-09-10T23:55:35.851+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using Or [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest], And [Not [MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[*/*]]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[*/*], useEquals=true, ignoredMediaTypes=[]]]
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint@7ca4ed9f
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2023-09-10T23:55:35.853+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@74626aab
Spring boot v3.1.2
If someone can help, I'd appreciate.
Simply defining the method in your configuration class is not enough. Spring security has a default security filter chain, and if you want to override some behavior you have to provide your own bean.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) { ... }
The @Bean
annotation is necessary because you want to communicate "here, use this method to create a SecurityFilterChain bean". Once the bean is present in the context, it will be automatically picked up.
To answer your question "should I add it in every single method in Spring boot or what?":
No, you should not. You add it when you want to specify that your method returns a bean to be managed by the spring context. Often you will be configuring some aspect of spring using this method, but in general your methods don't return beans.