Skip to content

Commit

Permalink
docker: require auth for Eureka on EUREKA_USERNAME (#3698)
Browse files Browse the repository at this point in the history
This allows the Eureka test image to accept EUREKA_USERNAME and
EUREKA_PASSWORD to require authentication accordingly without requiring
auth when they aren't set. This is important to test auth, but not break
our tests that do not require auth.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Andriy Redko <drreta@gmail.com>
  • Loading branch information
codefromthecrypt and reta authored Jan 22, 2024
1 parent 13e46f8 commit 5ff651f
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
9 changes: 9 additions & 0 deletions docker/test-images/zipkin-eureka/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>

<!-- Get rid of log warning saying to use Caffeine -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2015-2024 The OpenZipkin Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package zipkin.test;

import org.springframework.boot.context.properties.ConfigurationProperties;

/** Properties for configuring and building a {@link EurekaServer}. */
@ConfigurationProperties("eureka")
class EurekaProperties {

/** Optional username to require. */
private String username;

/** Optional password to require. */
private String password;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2015-2024 The OpenZipkin Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package zipkin.test;

import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.crypto.factory.PasswordEncoderFactories.createDelegatingPasswordEncoder;

/** This enables security, particularly only BASIC auth, when {@code EUREKA_USERNAME} is set. */
@Configuration
@ConditionalOnProperty("eureka.username")
@EnableConfigurationProperties(EurekaProperties.class)
@ImportAutoConfiguration(SecurityAutoConfiguration.class)
public class EurekaSecurity {
@Bean InMemoryUserDetailsManager userDetailsService(EurekaProperties props) {
PasswordEncoder encoder = createDelegatingPasswordEncoder();
UserDetails user = User.withUsername(props.getUsername())
.password(encoder.encode(props.getPassword()))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}

/**
* You have to disable CSRF to allow BASIC authenticating Eureka clients to operate.
* <p>
* See <a href="https://cloud.spring.io/spring-cloud-netflix/reference/html/#securing-the-eureka-server">Securing The Eureka Server</a>
*/
@Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.ignoringRequestMatchers("/eureka/**"));
http.authorizeHttpRequests(authz -> authz.requestMatchers("/eureka/**").authenticated())
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,23 @@
package zipkin.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.annotation.Import;

@SpringBootApplication
/**
* This disables automatic security configuration, deferring to {@linkplain EurekaSecurity}.
* Doing so allows Eureka to start as if spring-security wasn't in the classpath.
*/
@SpringBootApplication(
exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class}
)
@EnableEurekaServer
@Import(EurekaSecurity.class)
public class EurekaServer {

public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
Expand Down

0 comments on commit 5ff651f

Please sign in to comment.