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。