In our actual production environment, we need to consider a security issue, such as user login, or eureka server, which exposes its own rest API. If there is no security authentication, it means that other people can modify data information at will through rest API. This is a very terrible thing. In this article, we will discuss how eureka server is opened and recognized. Proof and how eureka client configures authentication information.
Public pom file dependencies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.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.RELEASE</spring-cloud.version>
</properties>
<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>
1. Ereka server project
1.1. Ereka server project pom:
<!--Plus the public dependence on the header of the article-->
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
<!--Privilege dependency, as long as pom With this dependency on files, permission checking is enabled by default for the project--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
1.2. Ereka server project startup class:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurkeaServerApplication { public static void main(String[] args) { SpringApplication.run(EurkeaServerApplication.class, args); } }
1.3. Ereka server project configuration file, path: eureka-server\ src main resources\
application-security.yml:
server: port: 8761 spring: security: basic: enabled: true user: name: admin password: Xk38CNHigBP5jK75 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ server: waitTimeInMsWhenSyncEmpty: 0 enableSelfPreservation: false
application.yml:
spring:
profiles:
active: security
Because spring-boot-starter-security opens CSRF checking by default, it is inappropriate for non-interface applications such as client side, but there is no way to disable configuration files. It needs to be disabled through Java configuration, as follows:
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; /** * Close the CSRF check for spring-boot-starter-security */ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http.csrf().disable(); } }
1.4. Start the eureka server project and execute the order:
mvn spring-boot:run
Open the command line terminal and execute curl-i http://localhost:8761/eureka/apps
curl -i http://localhost:8761/eureka/apps HTTP/1.1 401 Set-Cookie: JSESSIONID=554BCAF092D8D1ED3936C0CB09E91AF1; Path=/; HttpOnly WWW-Authenticate: Basic realm="Realm" X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Frame-Options: DENY Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Fri, 04 Oct 2019 07:31:57 GMT {"timestamp":"2019-10-04T07:31:57.888+0000","status":401,"error":"Unauthorized","message":"Unauthorized","path":"/eureka/apps"}
As you can see, the header of Authenticate is not passed, and the 401 status code is returned.
Next, use http basic's account password to pass Authenticate's header:
curl -i --basic -u admin:Xk38CNHigBP5jK75 http://localhost:8761/eureka/apps HTTP/1.1 200 Set-Cookie: JSESSIONID=CF1C0DE56415626494EC539A654CC543; Path=/; HttpOnly X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Frame-Options: DENY Content-Type: application/xml Transfer-Encoding: chunked Date: Fri, 04 Oct 2019 07:35:54 GMT <applications> <versions__delta>1</versions__delta> <apps__hashcode></apps__hashcode> </applications>
The request succeeded.
2. Ereka Client Project
2.1. eureka client project pom:
<!--Plus the public dependence on the header of the article-->
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2.2. Ereka Client Project Startup Class:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class EurekaClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); } }
2.3, eureka client project configuration file, path: eureka-client src main resources\
Because the eureka server project has opened the http basic authentication, the eureka client project also needs to add the corresponding account information transmission, here we specify by the configuration file.
application-security.yml:
server: port: 8081 spring: application: name: client1 eureka: client: security: basic: user: admin password: Xk38CNHigBP5jK75 serviceUrl: defaultZone: http://${eureka.client.security.basic.user}:${eureka.client.security.basic.password}@localhost:8761/eureka/
application.yml:
spring:
profiles:
active: security
Execution: curl-i -- basic-u admin: Xk38CNHigBP5jK75 http://localhost:8761/eureka/apps
curl -i --basic -u admin:Xk38CNHigBP5jK75 http://localhost:8761/eureka/apps HTTP/1.1 200 Set-Cookie: JSESSIONID=C7CE372067A44606E9D3DEA6B64AEDCD; Path=/; HttpOnly X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Frame-Options: DENY Content-Type: application/xml Transfer-Encoding: chunked Date: Fri, 04 Oct 2019 07:53:40 GMT <applications> <versions__delta>1</versions__delta> <apps__hashcode>UP_1_</apps__hashcode> <application> <name>CLIENT1</name> <instance> <instanceId>192.168.50.161:client1:8081</instanceId> <hostName>192.168.50.161</hostName> <app>CLIENT1</app> <ipAddr>192.168.50.161</ipAddr> <status>UP</status> <overriddenstatus>UNKNOWN</overriddenstatus> <port enabled="true">8081</port> <securePort enabled="false">443</securePort> <countryId>1</countryId> <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"> <name>MyOwn</name> </dataCenterInfo> <leaseInfo> <renewalIntervalInSecs>30</renewalIntervalInSecs> <durationInSecs>90</durationInSecs> <registrationTimestamp>1570175584067</registrationTimestamp> <lastRenewalTimestamp>1570175584067</lastRenewalTimestamp> <evictionTimestamp>0</evictionTimestamp> <serviceUpTimestamp>1570175584067</serviceUpTimestamp> </leaseInfo> <metadata> <management.port>8081</management.port> </metadata> <homePageUrl>http://192.168.50.161:8081/</homePageUrl> <statusPageUrl>http://192.168.50.161:8081/actuator/info</statusPageUrl> <healthCheckUrl>http://192.168.50.161:8081/actuator/health</healthCheckUrl> <vipAddress>client1</vipAddress> <secureVipAddress>client1</secureVipAddress> <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer> <lastUpdatedTimestamp>1570175584067</lastUpdatedTimestamp> <lastDirtyTimestamp>1570175583914</lastDirtyTimestamp> <actionType>ADDED</actionType> </instance> </application> </applications>
You can see that the eureka client has successfully registered with the server.