eureka server 开启认证
https://cloud.spring.io/spring-cloud-static/Greenwich.RELEASE/single/spring-cloud.html#_securing_the_eureka_server
https://docs.spring.io/spring-security/site/docs/5.2.15.RELEASE/reference/html5/
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
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; @SpringBootApplication(exclude= {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class}) @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
红字部分是要禁止自动配置,这里要实现的是根据serviceUrl 自动识别是否开启认证
import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.config.http.SessionCreationPolicy; import cn.xs.ambi.bas.log.Log; import cn.xs.ambi.bas.log.LogFactory; @EnableWebSecurity @ConditionalOnExpression("('${eureka.client.serviceUrl.defaultZone}').contains('@')") class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final Log log = LogFactory.getLog(WebSecurityConfig.class); // http://zhangsan:123456@localhost:9002/eureka @Value("${eureka.client.serviceUrl.defaultZone}") private String serviceUrl; @Override protected void configure(HttpSecurity http) throws Exception { http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER); http.csrf().disable(); http.authorizeRequests().antMatchers("/ping").permitAll().antMatchers("/**").authenticated().and().httpBasic(); } @SuppressWarnings("deprecation") @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { log.info("serviceUrl[{}]", serviceUrl); String pair = serviceUrl.split(",")[0].split("@")[0].split("//")[1]; String username = pair.split(":")[0]; String password = pair.split(":")[1]; auth.inMemoryAuthentication() .passwordEncoder(org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()) .withUser(username).password(password).roles("USER"); } }
注意心跳要放前面,其他都需要认证
关键代码spel表达式,这里取到属性值后判断是否是认证格式
@ConditionalOnExpression("('${eureka.client.serviceUrl.defaultZone}').contains('@')")
Authenticating with the Eureka Server
HTTP basic authentication is automatically added to your eureka client if one of the eureka.client.serviceUrl.defaultZone
URLs has credentials embedded in it (curl style, as follows: http://user:password@localhost:8761/eureka
). For more complex needs, you can create a @Bean
of type DiscoveryClientOptionalArgs
and inject ClientFilter
instances into it, all of which is applied to the calls from the client to the server.
Because of a limitation in Eureka, it is not possible to support per-server basic auth credentials, so only the first set that are found is used. |
之后额ureka client 注册时如果用户密码不正确是无法注册的
这种实现仅需配置apollo 通用eureka namespace ,只需改动 eureka.client.serviceUrl.defaultZone 就可以了