添加了 corsConfigurationSource 仍然报错 "has been blocked by CORS policy"
Added corsConfigurationSource and still an error "has been blocked by CORS policy"
我正在尝试将 Spring 安全连接到我的项目。
创建了安全配置 class
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/api/v1/user/register").permitAll()
.antMatchers("/auth/api/v1/admin/*").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
我正在从浏览器发送注册请求
http://localhost:15001/auth/api/v1/user/register
我得到了答案:
Access to XMLHttpRequest at 'http://localhost:15001/auth/api/v1/user/register' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
根据 Spring 文档,我添加了 corsConfigurationSource 方法:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/api/v1/user/register").permitAll()
.antMatchers("/auth/api/v1/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
我正在从浏览器发送注册请求
http://localhost:15001/auth/api/v1/user/register
我仍然得到同样的错误
Access to XMLHttpRequest at 'http://localhost:15001/auth/api/v1/user/register' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
为什么错误没有消失?
我知道还有另一种添加控制器的方法
@CrossOrigin(origins="http://localhost:4200″)
您也可以添加到页眉。
但我想弄清楚为什么这个方法不起作用。
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.12</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
这是我形成答案的代码
final UserDto userDto = userToUserDtoConverter.convert(optionalUser.get());
if (password.equals(UserUtils.encryptText(optionalAuth.get().getPassword()))) {
final HttpHeaders responseHeaders = new HttpHeaders();
final String token = jwtTokenProvider.createToken(optionalAuth.get().getName());
return confirmUserRegister(userDto, "Пользователь авторизован",
HttpStatus.OK, responseHeaders);
}
protected ResponseEntity<DataResponse<UserDto>> confirmUserRegister(
UserDto userDto, String message, HttpStatus httpStatus, HttpHeaders responseHeaders) {
final DataResponse<UserDto> response = new DataResponse<>();
response.setStatus(StatusType.SUCCESSFUL);
response.setData(userDto);
response.addMessage(httpStatus.value(), message);
return new ResponseEntity<>(response, responseHeaders, httpStatus);
}
这里是link项目enter link description here
这个项目还很原始。并且这是项目的副本,所以你可以随意编辑
如果是本地环境,则不需要配置Spring,而是修改angular配置。
在项目的 src
/ 文件夹中创建文件 proxy.conf.json
。
将以下内容添加到新的代理文件中:
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
在 CLI 配置文件中,angular.json,将 proxyConfig 选项添加到服务目标:
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.json"
},
...
到运行具有此代理配置的开发服务器,调用ng serve
。
更多详细信息here。配置 Spring CORS 的问题在于:
- 您正在尝试解决特定于开发环境的问题
- 这可能会将 CORS 配置泄漏到不需要它们的生产设置中,除非您实际上想要设置 CORS。
现在,在生产中要做什么?
这实际上取决于您如何捆绑代码。
如果您的 UI + Java 代码将在同一个可部署文件中,WAR 或 JAR,您不需要配置 CORS,因为它们将被部署在同一个文件中域 (https://apps.example.com
) 或同一上下文根 (https://apps.example.com/app
).
当您的 UI 和 java 代码不在同一个域或您希望将应用程序部署在其他域时, 需要配置 CORS (https://apps.example.**com**
) 从他们的页面访问您的 API。
请注意Spring,当你设置
configuration.setAllowCredentials(true);
Spring不接受:
configuration.setAllowedOrigins(Arrays.asList("*"));
您需要像这样一一配置所需的来源:
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
你的配置应该是这样的
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers", "Access-Control-Allow-Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", "Origin", "Cache-Control", "Content-Type", "Authorization"));
configuration.setAllowedMethods(Arrays.asList("DELETE", "GET", "POST", "PATCH", "PUT"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
你必须用这个更新你的配置方法:
Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.**cors().disable().and().csrf().disable()**
.
.
.
}
我正在尝试将 Spring 安全连接到我的项目。 创建了安全配置 class
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/api/v1/user/register").permitAll()
.antMatchers("/auth/api/v1/admin/*").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
我正在从浏览器发送注册请求
http://localhost:15001/auth/api/v1/user/register
我得到了答案:
Access to XMLHttpRequest at 'http://localhost:15001/auth/api/v1/user/register' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
根据 Spring 文档,我添加了 corsConfigurationSource 方法:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/api/v1/user/register").permitAll()
.antMatchers("/auth/api/v1/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
我正在从浏览器发送注册请求
http://localhost:15001/auth/api/v1/user/register
我仍然得到同样的错误
Access to XMLHttpRequest at 'http://localhost:15001/auth/api/v1/user/register' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
为什么错误没有消失?
我知道还有另一种添加控制器的方法
@CrossOrigin(origins="http://localhost:4200″)
您也可以添加到页眉。 但我想弄清楚为什么这个方法不起作用。
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.12</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
这是我形成答案的代码
final UserDto userDto = userToUserDtoConverter.convert(optionalUser.get());
if (password.equals(UserUtils.encryptText(optionalAuth.get().getPassword()))) {
final HttpHeaders responseHeaders = new HttpHeaders();
final String token = jwtTokenProvider.createToken(optionalAuth.get().getName());
return confirmUserRegister(userDto, "Пользователь авторизован",
HttpStatus.OK, responseHeaders);
}
protected ResponseEntity<DataResponse<UserDto>> confirmUserRegister(
UserDto userDto, String message, HttpStatus httpStatus, HttpHeaders responseHeaders) {
final DataResponse<UserDto> response = new DataResponse<>();
response.setStatus(StatusType.SUCCESSFUL);
response.setData(userDto);
response.addMessage(httpStatus.value(), message);
return new ResponseEntity<>(response, responseHeaders, httpStatus);
}
这里是link项目enter link description here
这个项目还很原始。并且这是项目的副本,所以你可以随意编辑
如果是本地环境,则不需要配置Spring,而是修改angular配置。
在项目的 src
/ 文件夹中创建文件 proxy.conf.json
。
将以下内容添加到新的代理文件中:
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
在 CLI 配置文件中,angular.json,将 proxyConfig 选项添加到服务目标:
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.json"
},
...
到运行具有此代理配置的开发服务器,调用ng serve
。
更多详细信息here。配置 Spring CORS 的问题在于:
- 您正在尝试解决特定于开发环境的问题
- 这可能会将 CORS 配置泄漏到不需要它们的生产设置中,除非您实际上想要设置 CORS。
现在,在生产中要做什么?
这实际上取决于您如何捆绑代码。
如果您的 UI + Java 代码将在同一个可部署文件中,WAR 或 JAR,您不需要配置 CORS,因为它们将被部署在同一个文件中域 (https://apps.example.com
) 或同一上下文根 (https://apps.example.com/app
).
当您的 UI 和 java 代码不在同一个域或您希望将应用程序部署在其他域时, 需要配置 CORS (https://apps.example.**com**
) 从他们的页面访问您的 API。
请注意Spring,当你设置
configuration.setAllowCredentials(true);
Spring不接受:
configuration.setAllowedOrigins(Arrays.asList("*"));
您需要像这样一一配置所需的来源:
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
你的配置应该是这样的
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers", "Access-Control-Allow-Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", "Origin", "Cache-Control", "Content-Type", "Authorization"));
configuration.setAllowedMethods(Arrays.asList("DELETE", "GET", "POST", "PATCH", "PUT"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
你必须用这个更新你的配置方法:
Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.**cors().disable().and().csrf().disable()**
.
.
.
}