webentwicklung-frage-antwort-db.com.de

CORS-Problem - Auf der angeforderten Ressource ist kein Header "Access-Control-Allow-Origin" vorhanden

Ich habe zwei Webanwendungen erstellt - Client- und Service-Apps.
Die Interaktion zwischen Client- und Service-Apps funktioniert problemlos, wenn sie in derselben Tomcat-Instanz bereitgestellt werden.
Wenn die Apps jedoch in separaten Tomcat-Instanzen (verschiedenen Computern) bereitgestellt werden, erhalte ich die folgende Fehlermeldung, wenn eine Anfrage an die Service-App gesendet wird.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 401

Meine Clientanwendung verwendet JQuery, HTML5 und Bootstrap.

Ein AJAX-Anruf wird wie unten gezeigt an den Service gerichtet:

var auth = "Basic " + btoa({usname} + ":" + {password});
var service_url = {serviceAppDomainName}/services;

if($("#registrationForm").valid()){
    var formData = JSON.stringify(getFormData(registrationForm));
    $.ajax({
        url: service_url+action,
        dataType: 'json',
        async: false,
        type: 'POST',
        headers:{
            "Authorization":auth
        },
        contentType: 'application/json',
        data: formData,
        success: function(data){
            //success code
        },
        error: function( jqXhr, textStatus, errorThrown ){
            alert( errorThrown );
        });
}

Meine Dienstanwendung verwendet Spring MVC, Spring Data JPA und Spring Security.

Ich habe die CorsConfiguration-Klasse wie folgt eingefügt:

CORSConfig.Java:

@Configuration
@EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter  {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("*");
    }
}

SecurityConfig.Java:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@ComponentScan(basePackages = "com.services", scopedProxy = ScopedProxyMode.INTERFACES)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationService")
    private UserDetailsService userDetailsService;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().fullyAuthenticated();
        http.httpBasic();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.csrf().disable();
    }

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

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }
}

Frühlingssicherheit Abhängigkeiten:

 <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.2.3.RELEASE</version>
</dependency>

Ich verwende Apache Tomcat Server für die Bereitstellung.

12
JavaDeveloper

Die Preflight-Anfrage von CORS verwendet HTTP OPTIONS ohne Berechtigungsnachweise, siehe Cross-Origin Resource Sharing :

Andernfalls stellen Sie eine preflight-Anforderung ein. Rufen Sie die Anforderungs-URL aus der Origin-Quelle Origin mit der Referrer-Quelle als überschreibende Referrer-Quelle ab, wobei das Flag für die manuelle Weiterleitung und das Blockierungscookies gesetzt sind. Verwenden Sie dazu die Methode OPTIONS und die folgenden zusätzlichen Einschränkungen:

  • Fügen Sie einen Access-Control-Request-Method-Header mit der Request-Methode als Headerfeldwert hinzu (auch wenn dies eine einfache Methode ist).
  • Wenn die Kopfzeilen der Autorenanforderung nicht leer sind, fügen Sie eine Kopfzeile der Kopfzeile der Zugriffskontrollanforderung ein, die als Kopffeldwert eine durch Kommas getrennte Liste der Kopfzeilennamen aus der Kopfzeile der Autorenanforderung in lexikografischer Reihenfolge enthält. Jede dieser Zeichen wird in ASCII konvertiert. Kleinbuchstaben (auch wenn einer oder mehrere einfache Header sind).
  • Schließen Sie die Autorenanforderungsheader aus.
  • Benutzeranmeldeinformationen ausschließen.
  • Schließen Sie den Anforderungsentitätstext aus.

Sie müssen anonymen Zugriff für HTTP OPTIONS zulassen. 

Ihr geänderter (und vereinfachter) Code:

@Override
protected void configure(HttpSecurity http) throws Exception {
   http
       .authorizeRequests()
           .andMatchers(HttpMethod.OPTIONS, "/**").permitAll()
           .antMatchers("/login").permitAll()
           .anyRequest().fullyAuthenticated()
           .and()
       .httpBasic()
           .and()
       .sessionManagement()
           .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
           .and()
       .csrf().disable();
}

Seit Spring Security 4.2.0 können Sie die integrierte Unterstützung verwenden, siehe Spring Security Reference :

19. CORS

Spring Framework bietet erstklassige Unterstützung für CORS. CORS muss vor Spring Security verarbeitet werden, da die Anforderung vor dem Flug keine Cookies enthält (d. H. JSESSIONID). Wenn die Anfrage keine Cookies enthält und Spring Security an erster Stelle steht, wird in der Anfrage festgestellt, dass der Benutzer nicht authentifiziert ist (da in der Anfrage keine Cookies vorhanden sind) und diese ablehnen.

Der einfachste Weg, um sicherzustellen, dass zuerst mit CORS gearbeitet wird, ist die Verwendung von CorsFilter. Benutzer können CorsFilter mit Spring Security integrieren, indem Sie mit CorsConfigurationSource Folgendes angeben:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          // by default uses a Bean by the name of corsConfigurationSource
          .cors().and()
          ...
  }

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
      CorsConfiguration configuration = new CorsConfiguration();
      configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
      configuration.setAllowedMethods(Arrays.asList("GET","POST"));
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      source.registerCorsConfiguration("/**", configuration);
      return source;
  }
}
10
dur

Seit Spring Security 4.1 ist dies der richtige Weg, um Spring Security CORS zu unterstützen (wird auch in Spring Boot 1.4/1.5 benötigt):

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    }
}

und:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.csrf().disable();
        http.cors();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(ImmutableList.of("*"));
        configuration.setAllowedMethods(ImmutableList.of("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));
        // setAllowCredentials(true) is important, otherwise:
        // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);
        // setAllowedHeaders is important! Without it, OPTIONS preflight request
        // will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

Tun Sie nichts , was der falsche Weg ist, um das Problem zu lösen:

  • http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
  • web.ignoring().antMatchers(HttpMethod.OPTIONS);

Referenz: http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html

11
Hendy Irawan

In meinem Fall habe ich einen Resource Server mit aktivierter OAuth-Sicherheit, und eine der oben genannten Lösungen hat nicht funktioniert. Nach einigem Debuggen und Googeln kam der Grund heraus. 

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}

Grundsätzlich ist in diesem Beispiel Ordered.HIGHEST_PRECEDENCE der Schlüssel! 

https://github.com/spring-projects/spring-security-oauth/issues/938

Verschiedene pom-Abhängigkeiten fügen verschiedene Arten von Filtern hinzu. Daher können Probleme aufgrund der Reihenfolge auftreten.

0
AntonIva