Spring Boot v2.5.2 - CORS 策略 - "No 'Access-Control-Allow-Origin' header is present on the requested resource"
Spring Boot v2.5.2 - CORS policy - "No 'Access-Control-Allow-Origin' header is present on the requested resource"
我有一个带有 Vue JS 的前端应用程序,我正在使用 axios 调用我的 Spring Boot API,使用 Spring Security.
Vue 在 http://localhost:8081
上 运行。
API 在 http://localhost:8080
上 运行
我已将 Spring 启动应用程序设置如下:
application.properties: 空
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.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demin</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
ApiApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
IndexController:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin(origins = "http://localhost:8081/")
@RestController
@RequestMapping("/api")
public class IndexController {
@GetMapping("/index")
public ResponseEntity<String> findTitle() {
System.err.println("Hello IndexController !");
return new ResponseEntity<>("Hello world", HttpStatus.OK);
}
}
安全配置:
import java.util.List;
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;
import org.springframework.web.cors.CorsConfiguration;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
corsConfiguration.setAllowedOrigins(List.of("http://localhost:8081"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setExposedHeaders(List.of("Authorization"));
http
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.cors().configurationSource(request -> corsConfiguration);
}
}
现在,当我从 Vue js 进行调用时:
axios.get('http://localhost:8080/api/index')
.then((response) => {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
我的浏览器returns:
Access to XMLHttpRequest at 'http://localhost:8080/api/index' from
origin 'http://localhost:8081' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
这似乎是一个常见问题,所以我尝试了很多“解决方案”,但我显然遗漏了一些东西,我需要一些帮助...
编辑:
编辑#2:
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
http.formLogin().disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
returns同样的错误。
编辑#3:
2021-07-23 07:39:49.050 INFO 3924 --- [ restartedMain] com.demin.api.ApiApplication : No active profile set, falling back to default profiles: default
2021-07-23 07:39:49.082 INFO 3924 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-07-23 07:39:49.082 INFO 3924 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2021-07-23 07:39:49.533 INFO 3924 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-07-23 07:39:49.542 INFO 3924 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 JPA repository interfaces.
2021-07-23 07:39:49.983 INFO 3924 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-07-23 07:39:49.992 INFO 3924 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-07-23 07:39:49.992 INFO 3924 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.48]
2021-07-23 07:39:50.063 INFO 3924 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-07-23 07:39:50.064 INFO 3924 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 980 ms
2021-07-23 07:39:50.084 INFO 3924 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-07-23 07:39:50.220 INFO 3924 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-07-23 07:39:50.225 INFO 3924 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:966f4eb4-9170-4c8f-a106-67ce4bac32bd'
2021-07-23 07:39:50.354 INFO 3924 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-07-23 07:39:50.395 INFO 3924 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
2021-07-23 07:39:50.496 INFO 3924 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-07-23 07:39:50.592 INFO 3924 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2021-07-23 07:39:50.763 INFO 3924 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-07-23 07:39:50.771 INFO 3924 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-07-23 07:39:50.803 WARN 3924 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-07-23 07:39:51.019 INFO 3924 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 5d615eab-a8ac-4024-9fc0-be44e58ac78e
2021-07-23 07:39:51.109 INFO 3924 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5d114f4, org.springframework.security.web.context.SecurityContextPersistenceFilter@3c920c43, org.springframework.security.web.header.HeaderWriterFilter@45adf32d, org.springframework.security.web.csrf.CsrfFilter@59560611, org.springframework.security.web.authentication.logout.LogoutFilter@3101ec7e, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@65bc50ad, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@2439fa5a, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@4f62b51e, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@42ca4d2d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3765695a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@154842ed, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5f512afa, org.springframework.security.web.session.SessionManagementFilter@180f71e7, org.springframework.security.web.access.ExceptionTranslationFilter@46815abf, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@611036c4]
2021-07-23 07:39:51.145 INFO 3924 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-07-23 07:39:51.173 INFO 3924 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-07-23 07:39:51.182 INFO 3924 --- [ restartedMain] com.demin.api.ApiApplication : Started ApiApplication in 2.434 seconds (JVM running for 3.184)
此问题与CORS
无关。
查看提供的小例子,问题出在文件夹结构上。
Springs main 函数使用注释 @SpringBootApplication
注释,api 文档指出:
This is a convenience annotation that is equivalent to declaring @Configuration, @EnableAutoConfiguration and @ComponentScan.
@ComponentScan
的文档说明如下:
Configures component scanning directives for use with @Configuration
classes. ... If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
注意最后一部分。
所以spring将扫描下面的所有包 class 被注释为@SpringBootApplication
以搜索classes用 @Configuration
.
注释的
提供的项目目录布局如下:
java
├── com
│ └─ demin
│ └── api
│ └── @SpringBootApplication
├── config
│ └── @Configuration
└── controller
└── @RestController
这意味着注释 class 中的 none 将从扫描中提取。
所以问题的解决方法是目录结构需要修改为:
java
└── com
└─ demin
└── api
├── @SpringBootApplication
├── config
│ └── @Configuration
└── controller
└── @RestController
为了 spring 能够扫描底层包并选择带注释的 classes。
或者如果您希望 spring 扫描特定位置的特定包,您可以在 @ComponentScan
注释中定义 basePackageClasses()
或 basePackages()
。或者只是特定的 classes.
当你拉入 spring-security-starter
时,你会得到一个 auto configuration defined for you which is defined in the Hello Spring Security
section of the Spring Security Reference Manual
并且由于 none 定义的配置甚至被扫描的应用程序拾取,这是当前正在使用的配置。其余端点也未加载。
如果启用并提供了未加载的配置和端点,则可以在调试日志中发现它们。
那么如何防止这种情况:
始终使用 Spring Initializr 生成项目。
遵循可信来源的教程,例如 spring 提供 several getting started guides
了解如何enable debug logging in different part of your spring application or for instance spring security
在您的配置中设置一个断点并检查它在启动时是否为偶数 运行。
我有一个带有 Vue JS 的前端应用程序,我正在使用 axios 调用我的 Spring Boot API,使用 Spring Security.
Vue 在 http://localhost:8081
上 运行。
API 在 http://localhost:8080
我已将 Spring 启动应用程序设置如下:
application.properties: 空
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.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demin</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
ApiApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
IndexController:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin(origins = "http://localhost:8081/")
@RestController
@RequestMapping("/api")
public class IndexController {
@GetMapping("/index")
public ResponseEntity<String> findTitle() {
System.err.println("Hello IndexController !");
return new ResponseEntity<>("Hello world", HttpStatus.OK);
}
}
安全配置:
import java.util.List;
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;
import org.springframework.web.cors.CorsConfiguration;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
corsConfiguration.setAllowedOrigins(List.of("http://localhost:8081"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setExposedHeaders(List.of("Authorization"));
http
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.cors().configurationSource(request -> corsConfiguration);
}
}
现在,当我从 Vue js 进行调用时:
axios.get('http://localhost:8080/api/index')
.then((response) => {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
我的浏览器returns:
Access to XMLHttpRequest at 'http://localhost:8080/api/index' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这似乎是一个常见问题,所以我尝试了很多“解决方案”,但我显然遗漏了一些东西,我需要一些帮助...
编辑:
编辑#2:
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
http.formLogin().disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
returns同样的错误。
编辑#3:
2021-07-23 07:39:49.050 INFO 3924 --- [ restartedMain] com.demin.api.ApiApplication : No active profile set, falling back to default profiles: default
2021-07-23 07:39:49.082 INFO 3924 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-07-23 07:39:49.082 INFO 3924 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2021-07-23 07:39:49.533 INFO 3924 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-07-23 07:39:49.542 INFO 3924 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 JPA repository interfaces.
2021-07-23 07:39:49.983 INFO 3924 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-07-23 07:39:49.992 INFO 3924 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-07-23 07:39:49.992 INFO 3924 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.48]
2021-07-23 07:39:50.063 INFO 3924 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-07-23 07:39:50.064 INFO 3924 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 980 ms
2021-07-23 07:39:50.084 INFO 3924 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-07-23 07:39:50.220 INFO 3924 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-07-23 07:39:50.225 INFO 3924 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:966f4eb4-9170-4c8f-a106-67ce4bac32bd'
2021-07-23 07:39:50.354 INFO 3924 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-07-23 07:39:50.395 INFO 3924 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
2021-07-23 07:39:50.496 INFO 3924 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-07-23 07:39:50.592 INFO 3924 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2021-07-23 07:39:50.763 INFO 3924 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-07-23 07:39:50.771 INFO 3924 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-07-23 07:39:50.803 WARN 3924 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-07-23 07:39:51.019 INFO 3924 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 5d615eab-a8ac-4024-9fc0-be44e58ac78e
2021-07-23 07:39:51.109 INFO 3924 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5d114f4, org.springframework.security.web.context.SecurityContextPersistenceFilter@3c920c43, org.springframework.security.web.header.HeaderWriterFilter@45adf32d, org.springframework.security.web.csrf.CsrfFilter@59560611, org.springframework.security.web.authentication.logout.LogoutFilter@3101ec7e, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@65bc50ad, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@2439fa5a, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@4f62b51e, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@42ca4d2d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3765695a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@154842ed, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5f512afa, org.springframework.security.web.session.SessionManagementFilter@180f71e7, org.springframework.security.web.access.ExceptionTranslationFilter@46815abf, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@611036c4]
2021-07-23 07:39:51.145 INFO 3924 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-07-23 07:39:51.173 INFO 3924 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-07-23 07:39:51.182 INFO 3924 --- [ restartedMain] com.demin.api.ApiApplication : Started ApiApplication in 2.434 seconds (JVM running for 3.184)
此问题与CORS
无关。
查看提供的小例子,问题出在文件夹结构上。
Springs main 函数使用注释 @SpringBootApplication
注释,api 文档指出:
This is a convenience annotation that is equivalent to declaring @Configuration, @EnableAutoConfiguration and @ComponentScan.
@ComponentScan
的文档说明如下:
Configures component scanning directives for use with
@Configuration
classes. ... If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
注意最后一部分。
所以spring将扫描下面的所有包 class 被注释为@SpringBootApplication
以搜索classes用 @Configuration
.
提供的项目目录布局如下:
java
├── com
│ └─ demin
│ └── api
│ └── @SpringBootApplication
├── config
│ └── @Configuration
└── controller
└── @RestController
这意味着注释 class 中的 none 将从扫描中提取。
所以问题的解决方法是目录结构需要修改为:
java
└── com
└─ demin
└── api
├── @SpringBootApplication
├── config
│ └── @Configuration
└── controller
└── @RestController
为了 spring 能够扫描底层包并选择带注释的 classes。
或者如果您希望 spring 扫描特定位置的特定包,您可以在 @ComponentScan
注释中定义 basePackageClasses()
或 basePackages()
。或者只是特定的 classes.
当你拉入 spring-security-starter
时,你会得到一个 auto configuration defined for you which is defined in the Hello Spring Security
section of the Spring Security Reference Manual
并且由于 none 定义的配置甚至被扫描的应用程序拾取,这是当前正在使用的配置。其余端点也未加载。
如果启用并提供了未加载的配置和端点,则可以在调试日志中发现它们。
那么如何防止这种情况:
始终使用 Spring Initializr 生成项目。
遵循可信来源的教程,例如 spring 提供 several getting started guides
了解如何enable debug logging in different part of your spring application or for instance spring security
在您的配置中设置一个断点并检查它在启动时是否为偶数 运行。