2016-11-03 3 views
0

Ich habe einen Spring Boot/Spring Data REST Dienst, der Zugriff auf eine Reihe von Ressourcen erlaubt. Einige dieser Ressourcen (z. B. /detections) sind frei zugänglich, andere (z. B. /users) benötigen grundlegende HTTP-Authentifizierung. Durch Testen des REST-Dienstes mit CURL funktioniert alles wie erwartet. Die Probleme treten auf, wenn ich versuche, über eine Angular2-Webanwendung auf den Dienst zuzugreifen.CORS Preflight Anfrage im Frühjahr Daten REST

In diesem Fall habe ich kein Problem, wenn die ungeschützten Zugriff auf Ressourcen http://api.mydomain.com/detections:

this.http.get(this.DETECTIONS_API_ENDPOINT).subscribe(
          response => { 
           ... 
          }, 
          error => { 
           ... 
          } 
        ); 

Aber wenn ich versuche, http://api.mydomain.com/users eine geschützte Ressource zuzugreifen, indem die erforderlichen Header mit dem korrekten Benutzernamen und Passwort übergeben:

let headers = new Headers(); 
    headers.append('Content-Type', 'application/json'); 
    headers.append('Authorization', 'Basic ' + btoa(username+':'+password)); 

    return this.http.get(this.USERS_API_ENDPOINT, { body: "", headers: headers }).subscribe(
          response => { 
           ... 
          }, 
          error => { 
           ... 
          } 
        ); 

Ich bekomme (in Firefox-Konsole) einen Fehler der sagt cross-origin request blocked... Reason: CORS preflight request unsuccessfull (Bitte beachten Sie, dass dies meine Übersetzung aus dem Italienischen ist. Ich konnte die genaue entsprechende Fehlermeldung in Englisch nicht finden. Die auf Der Unterschied zwischen den beiden Aufrufen scheint das Übergeben der Header im zweiten Fall zu sein, was das Senden einer anstelle einer GET Anfrage auslöst.

Dies ist meine Feder Sicherheitskonfiguration:

@Configuration 
public class MyAppConfigurationSecurity extends WebSecurityConfigurerAdapter { 

    private Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder(); 

    @Autowired 
    private UserDetailsService myAppUserService; 

    /** 
    * HttpSecurity URL configuration settings. Configure authentication necessary for POST but not for GET 
    */ 

    @Override 
    protected void configure(HttpSecurity http) throws Exception 
    { 
     http.csrf().disable() 
      .authorizeRequests() 
       .antMatchers(HttpMethod.GET, "/detections").permitAll() 
       .antMatchers(HttpMethod.GET, "/detections/search/findTop5ByOrderByTimestampDesc").permitAll() 
       .antMatchers("/users").hasAuthority("ADMIN") 
       .antMatchers("/roles").hasAuthority("ADMIN") 
       .antMatchers("**").authenticated() 
      .and().httpBasic().and() 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 
    } 


    /** 
    * Sets custom MyAppUserService bean as user detail service 
    */ 

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

} 

Dies ist die CORS Filterkonfiguration; Ich habe diese Klasse nach dem Vorschlag um Spring Data Rest and Cors hinzugefügt, und es löste zunächst mein CORS-Zugriffsproblem für den Zugriff auf die ungeschützten Ressourcen. Leider scheint es nicht im Fall der geschützten Ressource zu arbeiten:

@Configuration 
public class MyAppConfigurationCors { 

    @Bean 
    public CorsFilter corsFilter() { 

     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     CorsConfiguration config = new CorsConfiguration(); 
     config.setAllowCredentials(true); // you USUALLY want this 
     config.addAllowedOrigin("*"); 
     config.addAllowedHeader("*"); 
     config.addAllowedMethod("GET"); 
     config.addAllowedMethod("OPTIONS"); // I added this in a second phase, but nothing changes 
     source.registerCorsConfiguration("/**", config); 
     return new CorsFilter(source); 
    } 
} 
+0

check this link http://stackoverflow.com/a/40374505/4793153 – Eswar

+0

Es ist mir nicht ganz klar, wie das funktionieren soll: Ich habe versucht, meine Konfigurationsklasse 'MyAppConfigurationCors' durch die Filterkomponente wie im Fragetext zu ersetzen , dann habe ich versucht, den 'if (" OPTIONS "..." test "in der' doFilter'-Methode zu setzen, aber ich bin mir nicht sicher, ob ich die Dinge richtig mache. In jedem Fall habe ich immer noch den Fehler ... – chrx

Antwort

2

Siehe Dokumentation zum Frühling, wie CORS and Spring Security zu integrieren.

@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; 
    } 
} 
1

Sie die Filter der cors hinzufügen können, bevor das erste Spring Security heißt ChannelProcessingFilter Filter:

CORS muss zuerst verarbeitet werden. Der folgende Codeabschnitt wird helfen, mehr zu erklären.

protected void configure(HttpSecurity http) throws Exception { 
http.requiresChannel().antMatchers("/*").requires(ANY_CHANNEL).and() 
.authorizeRequests().antMatchers("/api/customer/**").permitAll() 
.antMatchers("/api/signin").permitAll() 
.antMatchers("/api/**").permitAll() 
.antMatchers("/**").permitAll().and() 
.addFilterBefore(corsFilter(), ChannelProcessingFilter.class) 
.and().csrf().disable(); 
} 

Wenn andere Informationen besuchen erforderlich ist, diese -: http://javamusings.com/enabling-cors-support-in-spring-framework/. Hinweis -: Ich bin der Autor des Posts.

Verwandte Themen