Spring Boot JWT CORS with Angular 6

后端 未结 5 918
伪装坚强ぢ
伪装坚强ぢ 2021-01-02 22:24

I am using JWT in my Spring Boot app. When I try to login from the Angular 6 client, I get the CORS error

Access to XMLHttpRequest at \'http://localhost:8082         


        
相关标签:
5条回答
  • 2021-01-02 22:36

    Since message is about your preflight request i.e. OPTIONS request,

    I guess, you need to do two things on server side / Spring Boot code ,

    1. Return OK from Authentication filter so need to add below in attemptAuthentication method as first check i.e. don't do real authentication for preflight requests,

    if (CorsUtils.isPreFlightRequest(httpServletRequest)) { httpServletResponse.setStatus(HttpServletResponse.SC_OK); return new Authentication() ; //whatever your token implementation class is - return an instance of it
    }

    CorsUtils is - org.springframework.web.cors.CorsUtils

    1. Let Spring Security Enter Authorized Options requests into System so add these lines in Security Config ,

    .authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

    You can allow unauthorized OPTIONS requests too but I guess , that wouldn't be a good idea. Also, try to narrow down "/**" to specific URLs if possible.

    0 讨论(0)
  • 2021-01-02 22:43

    I was also facing the same issue.When i tried from postman it worked fine but same call made from react app i faced issue.

    Generally we disable cors in configuration while working with the spring security. But here you should allow it. Check the below code snippet.

    Just added http.cors(); in below code

    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserDetailsService userDetailsService;
        
        @Autowired
        private JwtFilter jwtFilter;
    
            
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
                }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            
     http.csrf().disable().authorizeRequests().antMatchers("/secure/authenticate")
            .permitAll().anyRequest().authenticated()
            .and().exceptionHandling().and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);;
            http.cors();
                    
        }
    
        @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
        
        @Bean
        public PasswordEncoder getPasswordEncoder() {
            return NoOpPasswordEncoder.getInstance();
        }
        
        
    }
    
    0 讨论(0)
  • 2021-01-02 22:47

    I had a similar error and the problem was the name of the packages... Try to rename your packages in this model: groupId.artifactId.security.jwt

    0 讨论(0)
  • 2021-01-02 22:50

    1) Create a bean returning CorsFilter

    I did it in SecurityConfig class which extends WebSecurityConfigurerAdapter

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        private final JwtTokenProvider jwtTokenProvider;
    
        @Autowired
        public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
            this.jwtTokenProvider = jwtTokenProvider;
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            //.... 
            http.cors();
        }
    
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
            config.addAllowedMethod("OPTIONS");
            config.addAllowedMethod("GET");
            config.addAllowedMethod("POST");
            config.addAllowedMethod("PUT");
            config.addAllowedMethod("DELETE");
            source.registerCorsConfiguration("/**", config);
            return new CorsFilter(source);
        }
    }
    

    2) Provide this CorsFilter to the class extending SecurityConfigurerAdapter

    public class JwtConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
        private final JwtTokenProvider jwtTokenProvider; 
    
        public JwtConfigurer(JwtTokenProvider jwtTokenProvider) {
            this.jwtTokenProvider = jwtTokenProvider;
        }
        
        @Override
        public void configure(HttpSecurity httpSecurity) throws Exception {
            JwtTokenFilter jwtTokenFilter = new JwtTokenFilter(jwtTokenProvider);
            httpSecurity.addFilterBefore(
                    new SecurityConfig(jwtTokenProvider).corsFilter(), 
                    UsernamePasswordAuthenticationFilter.class);
            httpSecurity.addFilterBefore(
                    jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }
    

    3) Add in method configure(HttpSecurity http) { /* ... */ http.cors(); } in SecurityConfig class

    Shown in the first code snippet above.

    0 讨论(0)
  • 2021-01-02 22:58

    i had the same problem, finally i only added httpRequest.cors(); at the end of configure method in the WebSecurityConfig class and it worked well, the explanation of why is :

    explicitly the preflight requests are not excluded from authorization in Spring Security configuration. Remember that Spring Security secures all endpoints by default.

    As a result, API expects an authorization token in the OPTIONS request as well.

    Spring provides an out of the box solution to exclude OPTIONS requests from authorization checks:

    The cors()method will add the Spring-provided CorsFilter to the application context which in turn bypasses the authorization checks for OPTIONS requests.

    for all details https://www.baeldung.com/spring-security-cors-preflight

    0 讨论(0)
提交回复
热议问题