使用 Spring Boot 和 Angular 的 CORS 策略

CORS Policy with Spring boot and Angular

提问人:vinicius.vaga 提问时间:10/22/2023 更新时间:10/23/2023 访问量:55

问:

我正在开发一个必须登录到 SpringBoot 应用程序的 Angular 应用程序。后端的结构是使用用户名和密码执行身份验证,并在经过身份验证时将 JWT 令牌返回给前端。

当我使用 postman 时,此结构有效,如下所示。在此处输入图像描述 在此处输入图像描述

但是,当我使用应用程序发出这些请求时,会生成 CORS 策略错误。在此处输入图像描述这是我的 Angular 组件:import { Component } from '@angular/core';

import { FormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-loginscreen',
  templateUrl: './loginscreen.component.html',
  styleUrls: ['./loginscreen.component.css']
})
export class LoginscreenComponent {
  constructor(private httpClient: HttpClient) { }
  public inputUsername: string = "";
  public inputPassword: string = "";


  login() {
    // preparar requisição http
    // Suponhamos que você tenha uma URL e os dados de login
  const url = 'http://localhost:8080/auth/login';
  const dadosDeLogin = {
    username: this.inputUsername,
    password: this.inputPassword
  };
  const headers = { 'content-type': 'application/json'}  


  this.httpClient.post(url, dadosDeLogin, { headers })
  .subscribe(data => {
    console.log(data);
  })
 
  }

 

}

这是我的 SecurityFilter 类:

@Component
public class SecurityFilter extends OncePerRequestFilter {
    @Autowired
    TokenService tokenService;
    @Autowired
    AdministratorRepository administratorRepository;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        var token = this.recoverToken(request);
        if(token != null){
            var login = tokenService.validateToken(token);
            UserDetails user = administratorRepository.findByUsername(login);

            // Requests CORS
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");


            var authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request, response);
    }

    private String recoverToken(HttpServletRequest request) {
        var authHeader = request.getHeader("Authorization");
        if(authHeader == null) return null;
        return authHeader.replace("Bearer ", "");
    }
}

这是我的 SecurityConfig 类:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Autowired
    SecurityFilter securityFilter;
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .csrf(csrf -> csrf.disable())
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/auth/login")).permitAll()
                        .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/auth/register")).permitAll()
                        .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/users")).hasRole("ADMIN")
                        .anyRequest().authenticated()
                )
                .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

我已经尝试了几种方法通过在后端设置 CORS 策略来消除此错误,但似乎没有任何效果。你可以帮我吗?

我尝试通过后端启用跨源

Java Angular Spring CORS 策略

评论

0赞 MikeOne 10/22/2023
您的浏览器网络选项卡中究竟发生了什么?
0赞 vinicius.vaga 10/22/2023
触发登录请求后,第一个响应是 CORS 错误,其中包含以下信息: imgur.com/a/QRpofU4 然后触发另一个,返回 403,其中包含以下信息: imgur.com/hWdXRMa
0赞 jub0bs 10/22/2023
你不能这样做,仅仅是因为印前检查请求从不携带凭据。if(token != null){...}

答:

2赞 boolean 10/22/2023 #1

在 Angular 项目中,

  1. 转到文件夹,创建一个文件。srcproxy.conf.json
  2. 添加如下例所示的配置
  "/myapi": {
    "target": "http://localhost:8080/",
    "secure": false,
    "changeOrigin": true
  }
}

来自 Angular 的代理文档

0赞 kasmi zoubeir 10/23/2023 #2

试试这个创建类 CorsConfig

package (your package here)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                        .allowedHeaders("*");
            }
        };
    }
}

Secyruty配置

import com....;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.intercept.AuthorizationFilter;

@Configuration
@EnableMethodSecurity(prePostEnabled = false,
        securedEnabled = false,
        jsr250Enabled = true)
public class webSecurityConfig {
   private JWTRequestFilter jwtRequestFilter;

    public webSecurityConfig(JWTRequestFilter jwtRequestFilter) {
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Bean
    public SecurityFilterChain filterChain (HttpSecurity http) throws Exception{
        http.csrf().disable().cors().disable();
        //hello mr Filter chaine please add the filter jwtRequesFilter befor the authorization class
        //we gona run jwtRequestFilter befor the autorization class

        http.addFilterBefore(jwtRequestFilter, AuthorizationFilter.class);
      http.authorizeHttpRequests()
               .requestMatchers("...","your permit all path").permitAll()
           .requestMatchers("...**").hasAuthority("ADMIN")
             .requestMatchers("/category/**","your admin path here ..**").hasAuthority("ADMIN")




            .anyRequest().authenticated()**.and().cors();**

        return http.build();

    }


}

希望这对你有用