4
respostas

[Bug] Spring boot Cors

Alguém pode me ajudar com isso, está acontencendo seguinte erro na minh app angular:

Access to XMLHttpRequest at 'http://localhost:8080/autenticacao/login' 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.

a API que estou consumindo é minha tbm:

@EnableWebSecurity
@Configuration
public class SecurityConfiguration {
    
    @Autowired
    private SecurityFilter securityFilter;

    
    @Bean
    protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        
        
        return http.csrf(csrf -> csrf.disable())
                   .cors(cors -> cors.disable())
                   .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                   .authorizeHttpRequests(req -> {
                            req.requestMatchers(HttpMethod.POST, "/autenticacao/login").permitAll();
                            req.requestMatchers(HttpMethod.GET, "/swagger-ui/**").permitAll();
                            req.requestMatchers(HttpMethod.GET, "/actuator/**").permitAll();
                            req.requestMatchers(HttpMethod.GET, "/swagger-resources/**").permitAll();
                            req.requestMatchers(HttpMethod.GET, "/v3/api-docs/**").permitAll();
                            req.requestMatchers(HttpMethod.GET, "/webjars/**").permitAll();
                            req.anyRequest().authenticated();
                   })
                   .addFilterBefore(this.securityFilter, UsernamePasswordAuthenticationFilter.class)
                   .build();
    }
    

    @Bean
    protected AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception{
        return configuration.getAuthenticationManager();
    }
    
    @Bean
    protected PasswordEncoder passwordEncoder() throws Exception {
        return new BCryptPasswordEncoder();
    }
    
    public static void main(String[] args) {
        System.out.println(new BCryptPasswordEncoder().encode("Thais123"));
    }

}
@Configuration
public class CorsConfiguration implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        .allowedOrigins("*")
        .allowedMethods("*");
    }

}
@CrossOrigin
@Tag(name = "Autenticação", description = "Método para se autenticar na API")
@RestController
@RequestMapping("/autenticacao")
public class AutenticacaoController {
    
    private static Logger log = Logger.getLogger(AutenticacaoController.class);
    
    @Autowired
    private AuthenticationManager manager;
    
    @Autowired
    private TokenService tokenService;
    
    @PostMapping("login")
    public ResponseEntity<DadosTokenJWT> login(@RequestBody @Valid DadosLogin login) {
        
        log.info("Realizando o login: "+login.username());
        
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(login.username(), login.password());
        Authentication authenticate = manager.authenticate(authenticationToken);
        
        String token = this.tokenService.gerarToken((Usuario) authenticate.getPrincipal());
        
        log.info("HTTP ok");
        return ResponseEntity.ok(new DadosTokenJWT(token, "Bearer"));
    }

}
4 respostas

Ronielisson, bom dia.

Em algum momento você está passando a url como http://localhost:4200 ? pois no erro acima da de entender que é isso. Nós mostre como você está fazendo a request no Postman.

Obs.: De uma olhada nas suas variaveis de ambiente do postman. Caso encontrar alguma coisa com essa URL http://localhost:4200 troque para http://localhost:8080

Roniellison, bom dia!

Tente usar este bean na sua classe SecurityConfiguration:

@Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("*"));
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "TRACE", "CONNECT"));
        configuration.setAllowedHeaders(List.of("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
        }

E retire o argumento do método cors, deixando assim:

.cors()

E comente o trecho de configuração da sua classe CorsConfiguration:

//@Override
//    public void addCorsMappings(CorsRegistry registry) {
//        registry.addMapping("/**")
//       .allowedOrigins("*")
//        .allowedMethods("*");
// }

Boa noite, nenhuma das duas soluções funcionaram, retirei o método addCors... add o ben na configuração do spring boot.

e na solução a cima a url localhots:4200 é do meu sistema angular que está tentando acessar a minha api Spring por isso o cors localhost:8080 bloqueia o acesso.

Ronielisson,

Então ai e que ta, você precisa passar para a sua aplicação permitir a requisição vinda da url localhost:4200, normalmente no seu application.properties ou application.yml você passa essa configuração. Segue o exemplo da minha aplicação abaixo:

Ela permite requisições vinda de localhost:8080 e de localhost:3000. De uma olhada no seu arquivo de configurações.

cors:
  originPatterns: http://localhost:8080,http://localhost:3000
file:
  upload-dir: /temp
security:
  jwt:
    token:
      secret-key: 53cr37
      expire-length: 3600000
spring:
  datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/rest_pdv_padaria?useTimezone=true&serverTimezone=UTC
      username: root
      password: maxuel
  jpa:
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
    show-sql: false
  servlet:
    multipart:
      enabled: true
      file-size-threshold: 2KB
      max-file-size: 200MB
      max-request-size: 215MB
springdoc:
 pathsToMatch: 
   - /auth/**
   - /api/**/**
 swagger-ui:
  use-root-path: true

Essa parte do cors da minha aplicação foi configurada na classe abaixo de configuração

package br.com.leuxam.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import br.com.leuxam.serialization.converter.YamlJackson2HttpMessageConverter;

@Configuration
public class WebConfig implements WebMvcConfigurer{

    private static final MediaType MEDIA_TYPE_APPLICATION_YML = MediaType.valueOf("application/x-yaml");
    
    @Value("${cors.originPatterns:default}")
    private String corsOriginPatterns = "";
    
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new YamlJackson2HttpMessageConverter());
    }
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        var allowedOrigins = corsOriginPatterns.split(",");
        registry.addMapping("/**")
            .allowedMethods("*")
            .allowedOrigins(allowedOrigins)
        .allowCredentials(true);
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(false)
            .ignoreAcceptHeader(false)
            .useRegisteredExtensionsOnly(false)
            .defaultContentType(MediaType.APPLICATION_JSON)
                .mediaType("json", MediaType.APPLICATION_JSON)
                .mediaType("xml", MediaType.APPLICATION_XML)
                .mediaType("x-yaml", MEDIA_TYPE_APPLICATION_YML);
    }
    
}