Eureka Actual Warfare-4 [Open http basic privilege authentication]

Keywords: Java Spring curl encoding

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.

Posted by bloo on Fri, 04 Oct 2019 11:46:05 -0700