我想用基本身份验证来保护我的spring cloud gateway
。但我发现,当我添加spring-boot-starter-security
依赖项和基本配置时,网关在性能测试中的吞吐量很差。
- 安全-53.2秒
- 无安全-694.1/sec
怎么了?
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo-gateway</artifactId>
<version>0.0.1</version>
<name>demo-gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR11</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</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>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<includes>
<include>**/*Tests.java</include>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
</excludes>
<argLine>-Dfile.encoding=${project.build.sourceEncoding}</argLine>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
安全配置
@EnableWebFluxSecurity
public class SecurityWebFluxConfig {
@Bean
public MapReactiveUserDetailsService authentication() {
UserDetails user = User
.withUsername("user")
.password("password")
.roles("USER")
.build();
return new MapReactiveUserDetailsService(user);
}
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http.authorizeExchange()
.anyExchange().authenticated()
.and().httpBasic()
.and().build();
}
}
您之所以注意到这一点,是因为Spring Security利用自适应单向函数来存储密码。这些都是有意占用资源的,这意味着为每个请求验证用户名和密码将显著降低应用程序的性能。Spring Security(或任何其他库(都无法加快密码的验证,因为安全性是通过使验证资源密集型来获得的。
我鼓励您将长期凭据(即用户名和密码(交换为短期凭据(即会话、OAuth令牌等(,而不是使用HTTP基本身份验证。短期凭证可以快速验证,而不会丢失任何安全性。
Spring Security参考文档的密码存储部分对此有深入的解释。