CORS con stivale a molla e angolari non funzionanti


87

Sto cercando di chiamare gli endpoint REST su un'applicazione (applicazione di avvio a molla) da un'altra (angularjs). Le applicazioni sono in esecuzione sui seguenti host e porte.

  • Applicazione REST, utilizzando l'avvio a molla, http://localhost:8080
  • Applicazione HTML, utilizzando angularjs, http://localhost:50029

Sto anche usando spring-securitycon l'applicazione di avvio a molla. Dall'applicazione HTML, posso autenticarmi all'applicazione REST, ma, successivamente, non riesco ancora ad accedere a nessun endpoint REST. Ad esempio, ho un servizio angularjs definito come segue.

adminServices.factory('AdminService', ['$resource', '$http', 'conf', function($resource, $http, conf) {
    var s = {};
    s.isAdminLoggedIn = function(data) {
        return $http({
            method: 'GET',
            url: 'http://localhost:8080/api/admin/isloggedin',
            withCredentials: true,
            headers: {
                'X-Requested-With': 'XMLHttpRequest'
            }
        });
    };
    s.login = function(username, password) {
        var u = 'username=' + encodeURI(username);
        var p = 'password=' + encodeURI(password);
        var r = 'remember_me=1';
        var data = u + '&' + p + '&' + r;

        return $http({
            method: 'POST',
            url: 'http://localhost:8080/login',
            data: data,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        });
    };
    return s;
}]);

Il controller angularjs ha il seguente aspetto.

adminControllers.controller('LoginController', ['$scope', '$http', 'AdminService', function($scope, $http, AdminService) {
    $scope.username = '';
    $scope.password = '';

    $scope.signIn = function() {
        AdminService.login($scope.username, $scope.password)
            .success(function(d,s) {
                if(d['success']) {
                    console.log('ok authenticated, call another REST endpoint');
                    AdminService.isAdminLoggedIn()
                        .success(function(d,s) {
                            console.log('i can access a protected REST endpoint after logging in');
                        })
                        .error(function(d, s) { 
                            console.log('huh, error checking to see if admin is logged in');
                            $scope.reset();
                        });
                } else {
                    console.log('bad credentials?');
                }
            })
            .error(function(d, s) {
                console.log('huh, error happened!');
            });
    };
}]);

Durante la chiamata a http://localhost:8080/api/admin/isloggedin, ricevo un 401 Unauthorized.

Sul lato dell'applicazione REST, ho un filtro CORS simile al seguente.

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {

    @Override
    public void destroy() { }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        response.setHeader("Access-Control-Allow-Origin", "http://localhost:50029");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, X-Auth-Token");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        if(!"OPTIONS".equalsIgnoreCase(request.getMethod())) {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig config) throws ServletException { }
}

La mia configurazione della sicurezza primaverile è simile alla seguente.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    @Autowired
    private JsonAuthSuccessHandler jsonAuthSuccessHandler;

    @Autowired
    private JsonAuthFailureHandler jsonAuthFailureHandler;

    @Autowired
    private JsonLogoutSuccessHandler jsonLogoutSuccessHandler;

    @Autowired
    private AuthenticationProvider authenticationProvider;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    @Value("${rememberme.key}")
    private String rememberMeKey;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .exceptionHandling()
            .authenticationEntryPoint(restAuthenticationEntryPoint)
                .and()
            .authorizeRequests()
                .antMatchers("/api/admin/**").hasRole("ADMIN")
                .antMatchers("/", "/admin", "/css/**", "/js/**", "/fonts/**", "/api/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .successHandler(jsonAuthSuccessHandler)
                .failureHandler(jsonAuthFailureHandler)
                .permitAll()
                .and()
            .logout()
                .deleteCookies("remember-me", "JSESSIONID")
                .logoutSuccessHandler(jsonLogoutSuccessHandler)
                .permitAll()
                .and()
            .rememberMe()
                .userDetailsService(userDetailsService)
                .tokenRepository(persistentTokenRepository)
                .rememberMeCookieName("REMEMBER_ME")
                .rememberMeParameter("remember_me")
                .tokenValiditySeconds(1209600)
                .useSecureCookie(false)
                .key(rememberMeKey);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .authenticationProvider(authenticationProvider);
    }
}

Tutto ciò che i gestori stanno facendo è scrivere una risposta JSON in {success: true}base a se l'utente ha effettuato l'accesso, non è riuscito ad autenticarsi o si è disconnesso. Gli RestAuthenticationEntryPointappare come il seguente.

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest req, HttpServletResponse resp, AuthenticationException ex)
            throws IOException, ServletException {
        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }

}

Qualche idea su cosa mi sto perdendo o facendo male?


Suppongo che tu debba portare anche l'autenticazione, come un token o qualcosa del genere. Hai 2 server. Hai guardato a quel tutorial? spring.io/guides/tutorials/spring-security-and-angular-js
Gokhan Oner

@GokhanOner Come porto l'autenticazione? Questo è probabilmente il pezzo mancante di questo problema. Inoltre, sì, ho seguito quei tutorial e non pensavo che fossero in linea con il mio approccio. Le prime due parti si sono occupate dell'autenticazione Http-Basic, poi la terza parte si è occupata di Redis (non volevo o ho intenzione di ottenerlo come dipendenza), e poi l'ultimo tutorial riguardava il API Gatewaycloud con la primavera, che pensavo fosse eccessivo .
Jane Wayne

Suppongo che tu possa farlo senza il redis, è solo un archivio di cache di valori-chiave. È necessario memorizzare l'autenticazione e il token CSRF su un negozio, possibile all'interno della mappa al volo. La cosa fondamentale qui è la chiave di autenticazione. guarda l'esempio: github.com/dsyer/spring-security-angular/tree/master/… e la pagina con "resource server". Vedrai alcuni bean aggiuntivi definiti, anche l'ordine del filtro CORS è importante. E alcuni oggetti di scena. anche modifiche necessarie.
Gokhan Oner

Ok, ho fatto una rapida ricerca. Tutto ciò di cui hai bisogno, per sbarazzarti di Redis, è creare un bean springSessionRepositoryFilter, guarda github.com/spring-projects/spring-session/blob/1.0.0.RC1/… , e anche sessionRepository bean e in questo bean, invece di RedisOperationsSessionRepository, puoi usare MapSessionRepository, anch'esso nella sessione primaverile. E poi segui l'esempio.
Gokhan Oner

Risposte:


104
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

public SimpleCORSFilter() {
    log.info("SimpleCORSFilter init");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}

}

Non è necessario definire questo filtro in più, basta aggiungere questa classe. La primavera sarà scansionata e aggiungila per te. SimpleCORSFilter. Ecco l'esempio: spring-enable-cors


Alcune domande. 1) Dove dovrei mettere le costanti di stringa HEADERSe X_REDIRECT_LOCATION_HEADER? 2) La riga è request.getRequestURL());un errore di battitura o di copia / incolla? 3) Perché non controlli OPTIONSe continui semplicemente con la catena di filtri?
Jane Wayne

2
Ma blocca l'esecuzione di AuthenticationEntryPoint .. Guida
Pra_A

1
Grazie mille, mi ha aiutato incredibilmente nella mia lotta per far lavorare insieme primavera e tizzone. Salute amico!
Tomasz Szymanek

FindBugs non ama impostare un parametro di intestazione con: request.getHeader("Origin")come mostrato sopra a causa della suddivisione della risposta HTTP
Glenn

3
Se sono presenti altri filtri nella tua applicazione, questo filtro deve avere la massima precedenza annotando il filtro con @Order(Ordered.HIGHEST_PRECEDENCE) .
Shafiul

44

Ero stato in una situazione simile. Dopo aver fatto ricerche e test, ecco i miei risultati:

  1. Con Spring Boot, il modo consigliato per abilitare CORS globale è dichiarare all'interno di Spring MVC e combinato con una @CrossOriginconfigurazione a grana fine come:

    @Configuration
    public class CorsConfig {
    
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurerAdapter() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                            .allowedHeaders("*");
                }
            };
        }
    }
    
  2. Ora, poiché stai utilizzando Spring Security, devi abilitare CORS anche a livello di Spring Security per consentirgli di sfruttare la configurazione definita a livello di Spring MVC come:

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.cors().and()...
        }
    }
    

    Ecco un tutorial molto eccellente che spiega il supporto CORS nel framework Spring MVC.


3
ups funziona con questa modifica http .csrf () .disable () .cors () .and ()
marti_

1
@Osgux è bello sentirlo :) dato che sto usando JWT per l'autorizzazione e sono csrf al sicuro, non l'ho messo lì .. non dimenticare di votare se ha aiutato :)
Yogen Rai

sì, ho aggiunto +1 = D
marti_

@ Marcel che problema stai ricevendo?
Yogen Rai

Impossibile caricare <il mio indirizzo di riposo>: la risposta alla richiesta di verifica preliminare non supera il controllo di controllo degli accessi: nessuna intestazione "Access-Control-Allow-Origin" è presente sulla risorsa richiesta. L'accesso all'origine " localhost: 8090 " non è pertanto consentito.
Marcel

22

Se vuoi abilitare CORS senza usare filtri o senza file di configurazione, aggiungi

@CrossOrigin

nella parte superiore del controller e funziona.


4
Quali sono i rischi per la sicurezza seguendo questo approccio?
Balaji Vignesh

Ha funzionato per me, ho provato ad aggiungere le intestazioni direttamente alla risposta ma non ha funzionato poiché il preflight non è stato gestito. Penso che questo non sia protetto ma potrebbe essere utilizzato da alcune app interne.
amisiuryk

Ha funzionato per me. soluzione abbastanza pratica per l'applicazione interna.
Ajay Kumar

8

Per basarsi sulle altre risposte precedenti, nel caso in cui si disponga di un'applicazione del servizio REST di Spring Boot (non Spring MVC) con la sicurezza Spring, è sufficiente abilitare CORS tramite la sicurezza Spring (se si utilizza Spring MVC, utilizzare WebMvcConfigurer potrebbe essere necessario bean come menzionato da Yogen la strada da percorrere in quanto la sicurezza di Spring delegherà alla definizione CORS ivi menzionata)

Quindi è necessario disporre di una configurazione di sicurezza che faccia quanto segue:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    //other http security config
    http.cors().configurationSource(corsConfigurationSource());
}

//This can be customized as required
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    List<String> allowOrigins = Arrays.asList("*");
    configuration.setAllowedOrigins(allowOrigins);
    configuration.setAllowedMethods(singletonList("*"));
    configuration.setAllowedHeaders(singletonList("*"));
    //in case authentication is enabled this flag MUST be set, otherwise CORS requests will fail
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

}

Questo collegamento contiene ulteriori informazioni sullo stesso: https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors

Nota:

  1. Abilitare CORS per tutte le origini (*) per un'applicazione distribuita potrebbe non essere sempre una buona idea.
  2. CSRF può essere abilitato tramite la personalizzazione Spring HttpSecurity senza problemi
  3. Nel caso in cui l'autenticazione sia abilitata nell'app con Spring (tramite a UserDetailsServicead esempio), è configuration.setAllowCredentials(true);necessario aggiungere

Testato per Spring boot 2.0.0.RELEASE (ovvero Spring 5.0.4.RELEASE e Spring security 5.0.3.RELEASE)


Questo ha risolto il mio problema. Essendo nuovo di Spring e Spring Boot, mi sono reso conto che non stavo costruendo con Sring MVC. Avevo un client Vue.js. Altre risposte sembravano essere per Spring MVC, ma questa risposta si collegava bene con la mia autenticazione e autorizzazione già implementate.
jaletechs

Ciao @jaletechs, anch'io sto usando nuxtJs (un framework vuejs) ma quando si tratta di impostare i cookie, non funziona. saresti così gentile da aiutare su questo.
KAmit

6

Sto usando spring boot 2.1.0e quello che ha funzionato per me è stato

A. Aggiungi le mappature dei cors:

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

B. Aggiungi la configurazione di seguito a my HttpSecurityper la sicurezza primaverile

.cors().configurationSource(new CorsConfigurationSource() {

    @Override
    public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedHeaders(Collections.singletonList("*"));
        config.setAllowedMethods(Collections.singletonList("*"));
        config.addAllowedOrigin("*");
        config.setAllowCredentials(true);
        return config;
    }
})

Anche in caso di proxy Zuul puoi usare questo INVECE DI A e B (basta usarlo HttpSecurity.cors()per abilitarlo in Spring security):

@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("HEAD");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("DELETE");
    config.addAllowedMethod("PATCH");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

restituire nuovo CorsFilter (sorgente); non tale errore del costruttore
Aadam

@Aadam Stai usando la stessa versione dello stivale a molla che uso io?
Settembre GH

2.1.5 è in uso
Aadam

@Aadam Assicurati di utilizzare CorsFilter da org.springframework.web.filter.CorsFilter. Ho avuto lo stesso problema mentre lo usavo accidentalmente dai pacchetti catalina.
Settembre GH

5

Questo funziona per me:

@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter  {
   //...
   @Override
   protected void configure(HttpSecurity http) throws Exception {

       //...         

       http.cors().configurationSource(new CorsConfigurationSource() {

        @Override
        public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowedHeaders(Collections.singletonList("*"));
            config.setAllowedMethods(Collections.singletonList("*"));
            config.addAllowedOrigin("*");
            config.setAllowCredentials(true);
            return config;
        }
      });

      //...

   }

   //...

}

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e / o come questo codice risponde alla domanda ne migliora il valore a lungo termine.
Adriano Martins

1
Nel caso in cui l'autenticazione sia abilitata tramite Spring security, config.setAllowCredentials (true); DEVE essere inserito altrimenti le richieste CORS continueranno a non riuscire
Deepak

2

Per me l'unica cosa che ha funzionato al 100% quando si utilizza la protezione primaverile è stata di saltare tutta la lanugine aggiuntiva di filtri e fagioli extra e qualsiasi cosa "magica" indiretta che le persone continuassero a suggerire che funzionasse per loro ma non per me.

Invece costringilo a scrivere le intestazioni di cui hai bisogno con un semplice StaticHeadersWriter:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            // your security config here
            .authorizeRequests()
            .antMatchers(HttpMethod.TRACE, "/**").denyAll()
            .antMatchers("/admin/**").authenticated()
            .anyRequest().permitAll()
            .and().httpBasic()
            .and().headers().frameOptions().disable()
            .and().csrf().disable()
            .headers()
            // the headers you want here. This solved all my CORS problems! 
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Origin", "*"))
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Methods", "POST, GET"))
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Max-Age", "3600"))
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Credentials", "true"))
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization"));
    }
}

Questo è il modo più diretto ed esplicito che ho trovato per farlo. Spero che aiuti qualcuno.


1

Questo è ciò che ha funzionato per me.

@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.cors();
    }

}

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

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

}

1

Passo 1

Annotando il controller con @CrossOriginannotazione consentirà le configurazioni CORS.

@CrossOrigin
@RestController
public class SampleController { 
  .....
}

Passo 2

Spring ha già un CorsFilter anche se puoi semplicemente registrare il tuo CorsFilter come bean per fornire la tua configurazione come segue.

@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // Provide list of origins if you want multiple origins
    config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
    config.setAllowCredentials(true);
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

0

controlla questo:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    ...
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
    ...
}

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e / o come questo codice risponde alla domanda ne migliora il valore a lungo termine.
rollstuhlfahrer

0

L'estensione della classe WebSecurityConfigurerAdapter e l'override del metodo configure () nella classe @EnableWebSecurity funzionerebbero: Di seguito è riportato un esempio di classe

@Override
protected void configure(final HttpSecurity http) throws Exception {

         http
        .csrf().disable()
        .exceptionHandling();
         http.headers().cacheControl();

        @Override
        public CorsConfiguration getCorsConfiguration(final HttpServletRequest request) {
            return new CorsConfiguration().applyPermitDefaultValues();
        }
    });
   }
}

0

Se originariamente il tuo programma non utilizza la sicurezza Spring e non può permettersi una modifica del codice, la creazione di un semplice proxy inverso può fare il trucco. Nel mio caso, ho usato Nginx con la seguente configurazione:

http {
  server {
    listen 9090;
    location / {
      if ($request_method = 'OPTIONS') {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      #
      # Custom headers and headers various browsers *should* be OK with but aren't
      #
      add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
      #
      # Tell client that this pre-flight info is valid for 20 days
      #
      add_header 'Access-Control-Max-Age' 1728000;
      add_header 'Content-Type' 'text/plain; charset=utf-8';
      add_header 'Content-Length' 0;
      return 204;
      }
      if ($request_method = 'POST') {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
      add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
      }
      if ($request_method = 'GET') {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
      add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
      }

      proxy_pass http://localhost:8080;
    }
  }
}

Il mio programma ascolta : 8080 .

RIF: CORS su Nginx


0

Questa risposta copia la risposta @abosancic ma aggiunge ulteriore sicurezza per evitare l'exploit CORS .

Suggerimento 1: non riflettere l'origine in entrata così com'è senza controllare l'elenco degli host autorizzati ad accedere.

Suggerimento 2: consenti la richiesta con credenziali solo per gli host autorizzati.

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

    private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

    private List<String> allowedOrigins;

    public SimpleCORSFilter() {
        log.info("SimpleCORSFilter init");
        allowedOrigins = new ArrayList<>();
        allowedOrigins.add("https://mysafeorigin.com");
        allowedOrigins.add("https://itrustthissite.com");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        String allowedOrigin = getOriginToAllow(request.getHeader("Origin"));

        if(allowedOrigin != null) {
            response.setHeader("Access-Control-Allow-Origin", allowedOrigin);
            response.setHeader("Access-Control-Allow-Credentials", "true");
        }

        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    public String getOriginToAllow(String incomingOrigin) {
        if(allowedOrigins.contains(incomingOrigin.toLowerCase())) {
            return incomingOrigin;
        } else {
            return null;
        }
    }
}

0

Nella nostra app Spring Boot, abbiamo impostato CorsConfigurationSource in questo modo.

La sequenza di allowedOrignsprima aggiunta e poi impostazione applyPermitDefaultValues()consente a Spring di impostare i valori predefiniti per le intestazioni consentite, le intestazioni esposte, i metodi consentiti, ecc., Quindi non è necessario specificarli.

    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:8084"));
        configuration.applyPermitDefaultValues();

        UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
        configurationSource.registerCorsConfiguration("/**", configuration);
        return configurationSource;
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/api/**")
                .access("@authProvider.validateApiKey(request)")
                .anyRequest().authenticated()
                .and().cors()
                .and().csrf().disable()
                .httpBasic().authenticationEntryPoint(authenticationEntryPoint);

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

0

Basta creare una singola classe come, tutto andrà bene con questo:

        @Component
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public class MyCorsConfig implements Filter {

            @Override
            public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
                final HttpServletResponse response = (HttpServletResponse) res;
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
                response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, enctype");
                response.setHeader("Access-Control-Max-Age", "3600");
                if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
                    response.setStatus(HttpServletResponse.SC_OK);
                } else {
                    chain.doFilter(req, res);
                }
            }

            @Override
            public void destroy() {
            }

            @Override
            public void init(FilterConfig config) throws ServletException {
            }
        }

0

Questo è ciò che ha funzionato per me per disabilitare CORS tra Spring boot e React

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    /**
     * Overriding the CORS configuration to exposed required header for ussd to work
     *
     * @param registry CorsRegistry
     */

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(4800);
    }
}

Ho dovuto modificare la configurazione della sicurezza anche come di seguito:

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .cors().configurationSource(new CorsConfigurationSource() {

                @Override
                public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
                    CorsConfiguration config = new CorsConfiguration();
                    config.setAllowedHeaders(Collections.singletonList("*"));
                    config.setAllowedMethods(Collections.singletonList("*"));
                    config.addAllowedOrigin("*");
                    config.setAllowCredentials(true);
                    return config;
                }
            }).and()
                    .antMatcher("/api/**")
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and().httpBasic()
                    .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and().exceptionHandling().accessDeniedHandler(apiAccessDeniedHandler());
        }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.