如何使用基本身份验证保护 spring cloud eureka 服务?
我在同一台主机上设置了多个 eureka 服务器实例.他们使用主机名 eureka-primary、secondary 和third,它们被定义为主机文件中的本地主机别名,一切正常——它们都作为不同的实例可见并且彼此可用.
I set up multiple instances of eureka servers on the same host. They are using host names eureka-primary, secondary and tertiary which are defined as the localhost aliases in the hosts file and everything is working just fine - they are all visible and available to each other as different instances.
当我尝试使用 basic auth
和 this 保护 eureka 实例时,问题就开始了.这个想法是添加 spring 安全依赖,在 eureka 服务器上指定安全用户和密码,并将这些凭据放在 defaultZone
urls 中(配置如下),但这似乎不起作用.
The problem starts when I try to secure eureka instances with basic auth
and this. The idea is add spring security dependency, to specify the security user and password on eureka servers, and to put these credentials in the defaultZone
urls (configs are below), but this does not seem to work.
Eureka 实例甚至无法相互注册,当我尝试访问 Eureka 门户网站时,系统会提示我输入登录表单,然后重定向到仪表板.所有仪表板都运行良好,需要访问凭据.
Eureka instances can't even register to each other and when I try to access eureka web portal I am prompted with login form and then redirected to dashboard. All dashboards are working fine and need credentials to be accessed.
我正在使用 spring cloud Finchley.RC1
和 spring boot 2.0.1.RELEASE
和相同版本的 spring-boot-starter-security
和 spring-cloud-starter-netflix-eureka-server
.
I am using spring cloud Finchley.RC1
with spring boot 2.0.1.RELEASE
and the same version of spring-boot-starter-security
and spring-cloud-starter-netflix-eureka-server
.
尤里卡服务器 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>rs.microservices</groupId>
<artifactId>eurekaServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eurekaServer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RC1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
尤里卡服务器应用程序.yml
---
spring:
security:
user:
name: admin
password: admin
profiles: primary
application:
name: eureka-server-clustered
server:
port: 8011
eureka:
instance:
hostname: eureka-primary
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://admin:admin@eureka-secondary:8012/eureka/,http://admin:admin@eureka-tertiary:8013/eureka/
---
spring:
security:
user:
name: admin
password: admin
profiles: secondary
application:
name: eureka-server-clustered
server:
port: 8012
eureka:
instance:
hostname: eureka-secondary
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://admin:admin@eureka-primary:8013/eureka/,http://admin:admin@eureka-tertiary:8011/eureka/
---
spring:
security:
user:
name: admin
password: admin
profiles: tertiary
application:
name: eureka-server-clustered
server:
port: 8013
eureka:
instance:
hostname: eureka-tertiary
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://admin:admin@eureka-primary:8011/eureka/,http://admin:admin@eureka-secondary:8012/eureka/
微服务 bootstrap.yml
spring:
application:
name: someService
server:
port: 0
eureka:
client:
registerWithEureka: true
fetchRegistry: true
service-url:
defaultZone: http://admin:admin@localhost:8011/eureka/,http://admin:admin@localhost:8012/eureka/,http://admin:admin@localhost:8013/eureka/
我做错了什么?
*编辑
我已经找到了多个这样的解决方案在 Spring 云中保护 Eureka,但它们都没有真正解决我的问题 - 正如您所看到的,我们的配置是相同的.
I already found multiple solutions like this one Securing Eureka in Spring cloud, but none of them really fixed my problem - as you can see our configurations are identical.
已解决!
TL;DR问题是 CSRF
并且由于某种原因 spring 无法验证在 application.yml
TL;DR
The problem was the CSRF
and for some reason spring couldn't authenticate user configured in application.yml
所以我不得不重写 WebSecurityConfigurerAdapter
中的配置方法来禁用 csrf 并创建 inMemory 用户.还从 application.yml 中删除了 spring.security.user 属性.
So I had to override configure methods from WebSecurityConfigurerAdapter
to disable csrf and create inMemory user. Also removed spring.security.user attributes from application.yml.
Eureka 服务器 application.yml
现在看起来像:
Eureka server application.yml
now looks like:
---
spring:
profiles: primary
application:
name: eureka-server-clustered
server:
port: 8011
eureka:
instance:
hostname: eureka-primary
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://admin:admin@eureka-secondary:8012/eureka,http://admin:admin@eureka-tertiary:8013/eureka
---
spring:
profiles: secondary
application:
name: eureka-server-clustered
server:
port: 8012
eureka:
instance:
hostname: eureka-secondary
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://admin:admin@eureka-primary:8013/eureka,http://admin:admin@eureka-tertiary:8011/eureka
---
spring:
profiles: tertiary
application:
name: eureka-server-clustered
server:
port: 8013
eureka:
instance:
hostname: eureka-tertiary
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://admin:admin@eureka-primary:8011/eureka,http://admin:admin@eureka-secondary:8012/eureka
新创建的 WebSecurityConfig
类:
Newly created WebSecurityConfig
class:
import org.springframework.context.annotation.Configuration;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(NoOpPasswordEncoder.getInstance())
.withUser("admin").password("admin")
.authorities("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}