Eureka實戰-4【開啟http basic許可權認證】

  • 2019 年 10 月 4 日
  • 筆記

在我們實際生產環境中,都需要考慮到一個安全問題,比如用戶登錄,又或者是eureka server,它對外暴露的有自己的rest API,如果沒有安全認證,也就意味著別人可以通過rest API隨意修改數據資訊,這是一件非常恐怖的事情,這篇文章咱們詳談eureka server是如何開啟認證,以及eureka client是如何配置鑒權資訊。

 

公共pom文件依賴:

<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、eureka server工程

1.1、eureka server工程pom:

<!--加上文章頭部的公共依賴-->

<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
     
     <!--許可權依賴,只要pom文件有這個依賴,項目默認就已經開啟了許可權校驗--> <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、eureka server工程啟動類:

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、eureka server工程配置文件,路徑:eureka-serversrcmainresources

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

 

由於spring-boot-starter-security默認開啟了CSRF校驗,對於client端這類非介面應用來說,有些不合適,但是又沒有配置文件的方式可以禁用,需要通過Java配置,進行禁用,如下:

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;    /**   * 關閉spring-boot-starter-security的CSRF校驗   */  @EnableWebSecurity  public class SecurityConfig extends WebSecurityConfigurerAdapter {        @Override      protected void configure(HttpSecurity http) throws Exception {          super.configure(http);          http.csrf().disable();      }  }

 

1.4、啟動eureka server工程,執行命令:

mvn spring-boot:run

打開命令行終端,執行: 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"}

可以看出,沒有傳遞Authenticate的header,返回401狀態碼。

 

下面使用http basic的帳號密碼傳遞Authenticate的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>

請求成功。 

 

2、eureka client工程

2.1、eureka client工程pom:

<!--加上文章頭部的公共依賴-->

<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、eureka client工程啟動類:

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工程配置文件,路徑:eureka-clientsrcmainresources

由於eureka server工程開啟了http basic認證,eureka client工程也需要添加相應的帳號資訊來傳遞,這裡我們通過配置文件來指定。

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

 

執行: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>                                                                                               

可以看到eureka client已經成功註冊到server。