添加了 corsConfigurationSource,但仍然出现错误“已被 CORS 策略阻止”

ale*_*lex 5 spring-security

我正在尝试将 Spring Security 连接到我的项目。\n创建了 Security Config 类

\n
@Configuration\n@EnableWebSecurity\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    private final JwtTokenProvider jwtTokenProvider;\n\n    @Bean\n    @Override\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n    \n    public SecurityConfig(JwtTokenProvider jwtTokenProvider) {\n        this.jwtTokenProvider = jwtTokenProvider;\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n                .httpBasic().disable()\n                .cors().and().csrf().disable()\n                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n                .and()\n                .authorizeRequests()\n                .antMatchers("/auth/api/v1/user/register").permitAll()\n                .antMatchers("/auth/api/v1/admin/*").hasRole("ADMIN")\n                .anyRequest().authenticated()\n                .and()\n                .apply(new JwtConfigurer(jwtTokenProvider));\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我正在从浏览器发送注册请求

\n
http://localhost:15001/auth/api/v1/user/register\n
Run Code Online (Sandbox Code Playgroud)\n

我得到了答案:

\n
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.\n
Run Code Online (Sandbox Code Playgroud)\n

根据Spring文档,我添加了corsConfigurationSource方法:

\n
@Configuration\n@EnableWebSecurity\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    private final JwtTokenProvider jwtTokenProvider;\n\n    @Bean\n    @Override\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n    \n    public SecurityConfig(JwtTokenProvider jwtTokenProvider) {\n        this.jwtTokenProvider = jwtTokenProvider;\n    }\n\n    @Bean\n    CorsConfigurationSource corsConfigurationSource() {\n        CorsConfiguration configuration = new CorsConfiguration();\n        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));\n        configuration.setAllowedMethods(Arrays.asList("GET","POST"));\n        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();\n        source.registerCorsConfiguration("/**", configuration);\n        return source;\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n                .httpBasic().disable()\n                .cors().and().csrf().disable()\n                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n                .and()\n                .authorizeRequests()\n                .antMatchers("/auth/api/v1/user/register").permitAll()\n                .antMatchers("/auth/api/v1/admin/**").hasRole("ADMIN")\n                .anyRequest().authenticated()\n                .and()\n                .apply(new JwtConfigurer(jwtTokenProvider));\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我正在从浏览器发送注册请求

\n
http://localhost:15001/auth/api/v1/user/register\n
Run Code Online (Sandbox Code Playgroud)\n

我仍然遇到同样的错误

\n
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.\n
Run Code Online (Sandbox Code Playgroud)\n

为什么错误没有消失?

\n

我知道还有另一种方法可以添加到控制器上

\n
@CrossOrigin(origins="http://localhost:4200\xe2\x80\xb3)\n
Run Code Online (Sandbox Code Playgroud)\n

您还可以添加到标头。\n但我想弄清楚为什么此方法不起作用。

\n

pom.xml

\n
<parent>\n  <groupId>org.springframework.boot</groupId>\n  <artifactId>spring-boot-starter-parent</artifactId>\n  <version>2.4.12</version>\n    <relativePath/>\n</parent>\n\n<dependencies>\n  <dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter</artifactId>\n  </dependency>\n\n  <dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-security</artifactId>\n  </dependency>\n\n  <dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-test</artifactId>\n    <scope>test</scope>\n  </dependency>\n\n  <dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-web</artifactId>\n  </dependency>\n  <dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-data-jpa</artifactId>\n  </dependency>\n\n  <dependency>\n    <groupId>com.auth0</groupId>\n    <artifactId>java-jwt</artifactId>\n    <version>${jwt.version}</version>\n  </dependency>\n  <dependency>\n    <groupId>org.postgresql</groupId>\n    <artifactId>postgresql</artifactId>\n    <version>${postgres.version}</version>\n  </dependency>\n\n  <dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-configuration-processor</artifactId>\n    <optional>true</optional>\n  </dependency>\n</dependencies>\n
Run Code Online (Sandbox Code Playgroud)\n

这是我形成答案的代码

\n
final UserDto userDto = userToUserDtoConverter.convert(optionalUser.get());\nif (password.equals(UserUtils.encryptText(optionalAuth.get().getPassword()))) {\n  final HttpHeaders responseHeaders = new HttpHeaders();\n  final String token = jwtTokenProvider.createToken(optionalAuth.get().getName());\n  return confirmUserRegister(userDto, "\xd0\x9f\xd0\xbe\xd0\xbb\xd1\x8c\xd0\xb7\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8c \xd0\xb0\xd0\xb2\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb7\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd",\n    HttpStatus.OK, responseHeaders);\n}\n\nprotected ResponseEntity<DataResponse<UserDto>> confirmUserRegister(\n    UserDto userDto, String message, HttpStatus httpStatus, HttpHeaders responseHeaders) {\n  final DataResponse<UserDto> response = new DataResponse<>();\n  response.setStatus(StatusType.SUCCESSFUL);\n  response.setData(userDto);\n  response.addMessage(httpStatus.value(), message);\n  return new ResponseEntity<>(response, responseHeaders, httpStatus);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是项目的链接,在此处输入链接描述

\n

该项目还很原始。这是项目的副本,因此您可以根据需要进行编辑

\n

Par*_*ras 3

如果这是本地环境,则不需要配置 Spring,而是修改 Angular 配置。

proxy.conf.json在项目的 / 文件夹中创建一个文件src

将以下内容添加到新的代理文件中:

{
  "/api": {
    "target": "http://localhost:3000",
    "secure": false
  }
}
Run Code Online (Sandbox Code Playgroud)

在 CLI 配置文件 angular.json 中,将 proxyConfig 选项添加到服务目标:

...

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },
...
Run Code Online (Sandbox Code Playgroud)

要使用此代理配置运行开发服务器,请调用ng serve

更多详细信息请参见此处。配置 Spring CORS 的麻烦在于:

  • 您正在尝试解决开发环境的特定问题
  • 这可能会将 CORS 配置泄漏到生产设置中,除非您确实需要设置 CORS,否则不需要这些配置。

现在,在生产中该怎么办?

这实际上取决于您如何捆绑代码。

如果您的 UI + Java 代码将位于相同的可部署、WAR 或 JAR 中,则无需配置 CORS,因为它们将部署在相同的域 ( https://apps.example.com) 或相同的上下文根 ( https://apps.example.com/app) 上。

当您的 UI 和 java 代码不在同一域中或者您希望部署在其他域 ( ) 上的应用程序从其页面访问您的 API时,您确实需要配置 CORS。https://apps.example.**com**

请注意在春季,当您设置

configuration.setAllowCredentials(true);
Run Code Online (Sandbox Code Playgroud)

Spring 不接受:

configuration.setAllowedOrigins(Arrays.asList("*"));
Run Code Online (Sandbox Code Playgroud)

您需要一一配置所需的源,如下所示:

configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
Run Code Online (Sandbox Code Playgroud)