Description
Describe the bug
I'm trying to secure my 3 Eureka servers. I configured spring security through application.properties
, and disabled CSRF. The biggest difference I can see is that the docs are referencing spring security 5 and the deprecated/removed WebSecurityConfigurerAdapter
class. Since I'm on Spring Boot 3/Spring Security 6, I'm configuring via the SecurityFilterChain
bean.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().ignoringRequestMatchers("/eureka/**");
return http.build();
}
}
After configuring the credentials and disabling CSRF, the 3 servers start up fine and all registered replicas show as available. However, it appears that I don't need any credentials to access eureka. I was able to replicate this via curl and the web browser. I tried hitting the main eureka dashboard, API (/eureka/apps), and actuator. None require credentials to access.
I also tried manually configuring security through the SecurityFilterChain
bean, but that produced different results. My config looks like this:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().ignoringRequestMatchers("/eureka/**")
.and().securityMatcher("/**").authorizeHttpRequests().anyRequest().authenticated()
.and()
.formLogin().disable()
.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
List<UserDetails> users = new ArrayList<>();
users.add(
User.builder()
.username("user")
.password("password")
.authorities("USER")
.build()
);
return new InMemoryUserDetailsManager(users);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Under this config, security seems to work when using curl/a browser. Replication is not successful though. If I go to each individual server dashboard, I see different results for the eureka instances that are reported as UP:
I also see a lot of these messages in the logs:
2023-02-13T11:58:35.475-05:00 WARN 39218 --- [arget_eureka2-4] c.n.eureka.util.batcher.TaskExecutors : Discovery WorkerThread error
java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because the return value of "java.lang.Throwable.getMessage()" is null
at com.netflix.eureka.cluster.ReplicationTaskProcessor.maybeReadTimeOut(ReplicationTaskProcessor.java:196) ~[eureka-core-2.0.0.jar:2.0.0]
at com.netflix.eureka.cluster.ReplicationTaskProcessor.process(ReplicationTaskProcessor.java:95) ~[eureka-core-2.0.0.jar:2.0.0]
at com.netflix.eureka.util.batcher.TaskExecutors$BatchWorkerRunnable.run(TaskExecutors.java:190) ~[eureka-core-2.0.0.jar:2.0.0]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
I'm not sure if I'm configuring this correctly, or where I could be going wrong.
Sample
I pushed my code here (https://github.com/erbrecht/eureka-security) so you can hopefully replicate this issue. The main
branch contains the first scenario, where I added the spring.security.user.name and password in application.properties and just disabled CSRF via Java config.
The security2
branch is the second scenario, where I configure security strictly through Java.
I have 3 profiles using different hostnames and ports for each server. I also modified my hosts file like so:
127.0.0.1 localhost localhost.localdomain eureka1 eureka2 eureka3
Any help is greatly appreciated.