I've got a SpringBoot REST server working (with HTTPS mutual authentication). HTTP Get requests are working, and now I'm trying to HTTP Post requests working.
When I make a POST I get the error
curl $CURL_OPTS -X POST https://$CURL_HOSTS/api/my/endpoint1
{
"error": "Forbidden",
"path": "api/my/endpoint1",
"status": 403,
"timestamp": "2023-05-12T19:47:58.874+00:00"
}
I searched and found this solution: How to Solve 403 Error in Spring Boot Post Request
But after adding the code that is recommended in that solution, I get the error:
2023-05-12 21:22:00 UTC WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext -
Exception encountered during context initialization - cancelling
refresh attempt: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'springSecurityFilterChain' defined
in class path resource
[org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception;
nested exception is java.lang.IllegalStateException:
Found WebSecurityConfigurerAdapter as well as SecurityFilterChain.
Please select just one.
Below are the two classes that conflicting and causing this error. I'm searching for how incorporate what is needed from both of them either in the same file or in the same bean, I'm not sure what solution is needed.
Original File: Supports X509 and mutual authentication
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.AuthorityUtils;
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.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class X509AuthenticationServer {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.x509()
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.userDetailsService(userDetailsService());
log.info("X509AuthenticationServer: filterChain bean created");
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Allow any user to be valid
return new User(username, "",
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
}
};
}
}
Newly added file based on How to Solve 403 Error in Spring Boot Post Request
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
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.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception{
http.cors().and().csrf().disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Most of this was just copy/pasted from another project so a pointer to the SpringBoot or SpringWeb docs that explain this might also be helpful.
So far I haven't found anything combining these two issue so most likely it's a Spring concept I need to get clear in my brain.
NOTE: I have started trying combining the two files but so far haven't found a working solution.
Spring docs
https://docs.spring.io/spring-framework/docs/4.1.6.RELEASE/javadoc-api/index.html?org/springframework/context/annotation/Configuration.html - I'm not sure why/where the API docs are for
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
https://docs.spring.io/spring-framework/docs/5.3.9/javadoc-api/