Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unable to configure spring security with spring boot 3.0.2 #4161

Closed
erbrecht opened this issue Feb 13, 2023 · 13 comments
Closed

unable to configure spring security with spring boot 3.0.2 #4161

erbrecht opened this issue Feb 13, 2023 · 13 comments
Assignees
Labels
dependencies Pull requests that update a dependency file documentation
Milestone

Comments

@erbrecht
Copy link

erbrecht commented Feb 13, 2023

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:

eureka1

eureka2

eureka3

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.

@erbrecht
Copy link
Author

after a bit more debugging, it looks like the NPE message above comes from an org.apache.http.client.ClientProtocolException exception.

cause:

org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.

stacktrace - sorry for the screenshot, not sure if I can copy/paste from the debugger without copying each individual call

stacktrace

not sure if this helps, but it seems like a better clue than the NPE when trying to extract the original Throwable message.

this is from an older version of httpclient, but the issue may still be relevant:

https://issues.apache.org/jira/browse/HTTPCLIENT-951

I guess the apache library doesn't pass creds until the server tells it to, but on certain requests, like POSTS, the body (input stream) may have already been read, so the request can't be repeated without recreating the input stream. apparently the BufferedHttpEntity from http components core is repeatable. I do see that a buffered http entity should be used if buffering is enabled, which looks like the case since this is returning the buffered entity:

buffered

again, not sure if this helps, is relevant to the main issue, or if this is just a bad path to go down. hopefully this is useful, even if just to discard a potential path to investigate.

@Been24
Copy link

Been24 commented Apr 6, 2023

any solutions?

@OlgaMaciaszek
Copy link
Collaborator

Thanks a lot for reporting. We're looking at it. Should be able to get back about this at the end of this week or the beginning of next.

@hazartilirot
Copy link

I was going to find a solution and stumbled across the topic. 🥳

Screenshot 2023-04-12 at 00 21 43

@OlgaMaciaszek
Copy link
Collaborator

Thanks, @erbrecht @Been24 @hazartilirot . I have taken a look at this. The simplest way to configure SecurityFilterChain to disable that CSRF check while maintaining the default setup, would probably be something like this:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
	http.authorizeHttpRequests((authz) -> authz
					.anyRequest().authenticated()
			)
			.httpBasic(withDefaults());
	http.csrf().ignoringRequestMatchers("/eureka/**");
	return http.build();
}

I have been able to replicate replication errors with this setup as well. Working on this issue.

@Nathan-ZR
Copy link

@OlgaMaciaszek I also encountered the same situation as erbrecht. I configured it with reference to your configuration file. When I started it, I found that when I entered user and password, an error would be reported directly.
java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because the return value of "java.lang.Throwable.getMessage()" is null.Looking forward to hearing from you.
I don't know if there is a problem with my configuration file? My configuration file code is shown in the image below.
image

@OlgaMaciaszek
Copy link
Collaborator

Yes, @Nathan-ZR, the NPE is due to lack of handling of null messages. I have submitted a fix for that to Netflix/Eureka, however this is not going to solve the problem. There are 401s being returned - looking further into that now.

@OlgaMaciaszek
Copy link
Collaborator

The proper Basic Auth header is not being added. The bug seems to be in Netflix/Eureka rather than in Spring Cloud Netflix, but will take a look at it anyway (probably at the beginning of the next week).

@fede843
Copy link

fede843 commented Jun 8, 2023

Hello. We are having the same issue with a similar configuration. Looking forward to hearing from this.

@yanping891003
Copy link

We have the same issue and look forward to news

@OlgaMaciaszek
Copy link
Collaborator

Should be fixed when in Netflix/eureka. Have submitted a PR with fix.

@OlgaMaciaszek OlgaMaciaszek added documentation dependencies Pull requests that update a dependency file and removed in progress labels Jun 16, 2023
@OlgaMaciaszek
Copy link
Collaborator

Have updated the sample and the docs as well.

@OlgaMaciaszek OlgaMaciaszek added this to the 4.0.3 milestone Jun 22, 2023
@OlgaMaciaszek
Copy link
Collaborator

Spring Cloud Netflix 4.0.x and main updated to fixed Netflix/Eureka version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file documentation
Projects
No open projects
Status: Done
Status: Done
Development

No branches or pull requests

7 participants