Cross-Origin Resource Sharing with Spring Security

后端 未结 8 1572
暖寄归人
暖寄归人 2020-12-01 04:39

I\'m trying to make CORS play nicely with Spring Security but it\'s not complying. I made the changes described in this article and changing this line in applicationCo

8条回答
  •  再見小時候
    2020-12-01 05:12

    Since main part of question is about unathorized CORS POST-request to login point I immediately point you to step 2.

    But regarding to answers count this is the most relevant question to Spring Security CORS request. So I will describe more elegant solution for configuring CORS with Spring Security. Because except rare situations it is not necessary to create filters/interceptors/… to put anything in response. We will do that declaratively by Spring. Since Spring Framework 4.2 we have CORS-stuff like filter, processor, etc out-of-the-box. And some links to read 1 2.

    Let's go:

    1. prepare CORS configuration source.

    It can be done in different ways:

    • as global Spring MVC CORS config (in configuration classes like WebMvcConfigurerAdapter)

      ...
          @Override
          public void addCorsMappings(CorsRegistry registry) {
              registry.addMapping("/**")
                  .allowedOrigins("*")
                  ...
          }
      
    • as separate corsConfigurationSource bean

      @Bean
      CorsConfigurationSource corsConfigurationSource() {
          CorsConfiguration config = new CorsConfiguration();
          config.applyPermitDefaultValues();
      
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          source.registerCorsConfiguration("/**", config);
      }
      
    • as external class (which can be used via constructor or autowired as a component)

      // @Component // <- for autowiring
      class CorsConfig extends UrlBasedCorsConfigurationSource {
      
          CorsConfig() {
              orsConfiguration config = new CorsConfiguration();
              config.applyPermitDefaultValues(); // <- frequantly used values
      
              this.registerCorsConfiguration("/**", config);
          }
      }
      

    2. enable CORS support with the defined configuration

    We will enable CORS support in Spring Security classes like WebSecurityConfigurerAdapter. Be sure that corsConfigurationSource is accessible for this support. Else provide it via @Resource autowiring or set explicitly (see in example). Also we let unauthorized access to some endpoints like login:

        ...
        // @Resource // <- for autowired solution
        // CorseConfigurationSource corsConfig;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.cors();
    
            // or autowiring
            // http.cors().configurationSource(corsConfig);
    
            // or direct set
            // http.cors().configurationSource(new CorsConfig());
    
            http.authorizeRequests()
                    .antMatchers("/login").permitAll() // without this line login point will be unaccessible for authorized access
                    .antMatchers("/*").hasAnyAuthority(Authority.all()); // <- all other security stuff
        }
    

    3. customize CORS config

    If base config works then we can customize mappings, origins, etc. Even add several configurations for different mappings. For example, I explicitly declare all CORS parameters and let UrlPathHelper to not trim my servlet path:

    class RestCorsConfig extends UrlBasedCorsConfigurationSource {
    
        RestCorsConfig() {
            this.setCorsConfigurations(Collections.singletonMap("/**", corsConfig()));
            this.setAlwaysUseFullPath(true);
        }
    
        private static CorsConfiguration corsConfig() {
            CorsConfiguration config = new CorsConfiguration();
            config.addAllowedHeader("*");
            config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
            config.setAllowCredentials(true);
            config.addAllowedOrigin("*");
            config.setMaxAge(3600L);
            return config;
        }
    }
    

    4. troubleshooting

    To debug my problem I was tracing org.springframework.web.filter.CorsFilter#doFilterInternal method. And I saw that CorsConfiguration search returns null because Spring MVC global CORS configuration was unseen by Spring Security. So I used solution with direct usage of external class:

    http.cors().configurationSource(corsConfig);
    

提交回复
热议问题