Yaylı ve açılı CORS çalışmıyor


87

Bir uygulamada (yaylı önyükleme uygulaması) diğerinden (angularjs) REST uç noktaları aramaya çalışıyorum. Uygulamalar aşağıdaki ana bilgisayarlarda ve bağlantı noktalarında çalışıyor.

  • Yaylı önyükleme kullanarak REST uygulaması, http://localhost:8080
  • Angularjs kullanarak HTML uygulaması, http://localhost:50029

spring-securityYaylı önyükleme uygulamasıyla da kullanıyorum . HTML uygulamasından, REST uygulamasının kimliğini doğrulayabilirim, ancak bundan sonra hala herhangi bir REST uç noktasına erişemiyorum. Örneğin, aşağıdaki gibi tanımlanmış bir angularjs servisim var.

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;
}]);

Angularjs denetleyicisi aşağıdaki gibi görünür.

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!');
            });
    };
}]);

Çağrımda http://localhost:8080/api/admin/isloggedinbir 401 Unauthorized.

REST uygulaması tarafında, aşağıdaki gibi görünen bir CORS filtrem var.

@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 { }
}

Yaylı güvenlik yapılandırmam aşağıdaki gibi görünüyor.

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

İşleyicilerin yaptığı tek şey {success: true}, kullanıcının oturum açmış, kimlik doğrulaması yapmamış veya oturumu kapatmış olmasına bağlı olarak bir JSON yanıtı yazmaktır . RestAuthenticationEntryPointBakışlar aşağıdaki gibi.

@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");
    }

}

Neyi kaçırdığım veya yanlış yaptığım hakkında bir fikriniz var mı?


Sanırım kimlik doğrulamasını da bir token veya başka bir şey gibi taşımanız gerekiyor. 2 sunucunuz var. O öğreticiye baktın mı? spring.io/guides/tutorials/spring-security-and-angular-js
Gokhan Öner

@GokhanOner Kimlik doğrulamasını nasıl taşıyabilirim? Muhtemelen bu sorunun eksik parçası budur. Ayrıca, evet, bu eğitimlerden geçtim ve yaklaşımımla uyumlu olduklarını düşünmedim. İlk iki bölüm Http-Basic kimlik doğrulamasıyla ilgilendi, ardından üçüncü bölüm Redis ile ilgilendi (bunu bir bağımlılık olarak almayı istemedim veya planlamadım) ve sonra son öğretici, API Gatewayaşırı öldürme olduğunu düşündüğüm bahar bulutu ile ilgiliydi. .
Jane Wayne

Sanırım bunu redis olmadan yapabilirsiniz, bu sadece bir anahtar-değer önbellek deposu. Kimlik doğrulamasını ve CSRF belirtecini bir mağazada, olası anında harita içinde depolamanız gerekir. Buradaki anahtar şey kimlik doğrulama anahtarıdır. örneğe bakın: github.com/dsyer/spring-security-angular/tree/master/… ve "kaynak sunucu" içeren sayfaya bakın. Bazı ek çekirdeklerin tanımlandığını göreceksiniz, CORS filtresinin sırası da önemlidir. Ve biraz pervane. değişiklikler de gereklidir.
Gökhan Öner

Tamam, hızlı bir araştırma yaptım. Redis'ten kurtulmak için ihtiyacınız olan tek şey bir springSessionRepositoryFilter bean sandıklamak, github.com/spring-projects/spring-session/blob/1.0.0.RC1/… ve ayrıca sessionRepository bean ve bu fasulyeye bakmak , RedisOperationsSessionRepository yerine, yine bahar oturumunda olan MapSessionRepository'yi kullanabilirsiniz. Ve sonra örneği takip edin.
Gökhan Öner

Yanıtlar:


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() {
}

}

Fazladan bu filtreyi tanımlamaya gerek yok, sadece bu sınıfı ekleyin. Bahar taranacak ve sizin için ekleyecek. SimpleCORSFilter. İşte örnek: yaylı korseler


Birkaç soru. 1) Dize sabitlerini nereye koymalıyım HEADERSveX_REDIRECT_LOCATION_HEADER ? 2) Satır request.getRequestURL());bir yazım hatası mı yoksa kopyalama / yapıştırma hatası mı? 3) Neden OPTIONSfiltre zincirini kontrol edip basitçe devam etmiyorsunuz ?
Jane Wayne

2
Ancak AuthenticationEntryPoint'i çalıştırmayı engeller .. Lütfen rehberlik edin
Pra_A

1
Çok teşekkür ederim, bahar ve köz mücadelemde birlikte çalışmama çok yardımcı oldu. Şerefe arkadaşlar!
Tomasz Szymanek

FindBugs, HTTP yanıt bölünmesirequest.getHeader("Origin") nedeniyle yukarıda gösterildiği gibi bir başlık parametresi ayarlamayı sevmez
Glenn 13

3
Uygulamanızda başka filtreler varsa, filtreye ile açıklama ekleyerek bu filtrenin en yüksek önceliğe sahip olması gerekir @Order(Ordered.HIGHEST_PRECEDENCE) .
Shafiul

44

Ben de benzer durumdaydım. Araştırma ve test yaptıktan sonra, işte bulgularım:

  1. Spring Boot ile, global CORS'u etkinleştirmenin önerilen yolu, Spring MVC içinde bildirmek ve aşağıdaki @CrossOrigingibi ince taneli yapılandırmayla birleştirmektir :

    @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. Şimdi, Spring Security kullandığınız için, CORS'u Spring Security seviyesinde etkinleştirmeniz ve Spring MVC seviyesinde aşağıdaki şekilde tanımlanan yapılandırmadan yararlanmasına izin vermeniz gerekir:

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

    İşte Spring MVC çerçevesindeki CORS desteğini açıklayan çok mükemmel bir öğretici.


3
ups bu değişiklikle çalışır http .csrf () .disable () .cors (). ve ()
marti_

1
@Osgux bunu duyduğuma sevindim :) yetkilendirme için JWT kullandığım ve csrf güvenli oldukları için oraya koymadım .. yardım ederse yükseltmeyi unutma :)
Yogen Rai

evet +1 = D
marti_

@Marcel ne sorunu alıyorsun?
Yogen Rai

<Dinlenme adresim> yüklenemedi: Ön kontrol isteğine verilen yanıt, erişim kontrol kontrolünü geçemiyor: İstenen kaynakta 'Access-Control-Allow-Origin' başlığı yok. Menşe ' localhost: 8090 ' bu nedenle erişimine izin verilmiyor.
Marcel

23

CORS'u filtre kullanmadan veya yapılandırma dosyası olmadan etkinleştirmek istiyorsanız, sadece şunu ekleyin:

@CrossOrigin

denetleyicinizin üstüne ve işe yarıyor.


4
Bu yaklaşımı izleyerek güvenlik riskleri nelerdir?
Balaji Vignesh

Benim için çalıştı, yanıta doğrudan başlıklar eklemeye çalıştım ama ön kontrol yapılmadığı için işe yaramadı. Bunun güvenli olmadığını düşünüyorum, ancak bazı dahili uygulamalarda kullanılabilir.
amisiuryk

Benim için çalıştı. dahili uygulama için oldukça kullanışlı bir çözüm.
Ajay Kumar

8

Yukarıdaki diğer cevapların üzerine inşa etmek için, Spring güvenliğine sahip bir Spring boot REST servis uygulamanız (Spring MVC değil) varsa, o zaman CORS'u Spring güvenliği üzerinden etkinleştirmek yeterlidir (Spring MVC kullanıyorsanız WebMvcConfigurer, Yogen tarafından belirtildiği gibi bir fasulye kullanmak olabilir. Spring güvenliğinin burada belirtilen CORS tanımına delege edeceği yol olarak)

Bu nedenle, aşağıdakileri yapan bir güvenlik yapılandırmasına sahip olmanız gerekir:

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

}

Bu bağlantı aynı konuda daha fazla bilgi içerir: https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors

Not:

  1. Bir prod konuşlandırılmış uygulama için tüm kaynaklar için (*) CORS'u etkinleştirmek her zaman iyi bir fikir olmayabilir.
  2. CSRF, Spring HttpSecurity özelleştirmesiyle herhangi bir sorun olmadan etkinleştirilebilir
  3. Spring ile uygulamada kimlik doğrulamasını etkinleştirdiyseniz ( UserDetailsServiceörneğin bir aracılığıyla ), o configuration.setAllowCredentials(true);zaman eklenmelidir

Spring boot 2.0.0.RELEASE için test edildi (yani, Spring 5.0.4.RELEASE ve Spring security 5.0.3.RELEASE)


Bu benim sorunumu çözdü. Spring ve Spring Boot'ta yeni olduğum için Sring MVC ile inşaat yapmadığımı fark ettim. Bir Vue.js İstemcim vardı. Diğer yanıtlar Spring MVC için görünüyordu, ancak bu yanıt benim zaten uygulanan kimlik doğrulama ve yetkilendirme ile güzelce takıldı.
jaletechs

Merhaba @jaletechs, ben de nuxtJs (bir vuejs çerçevesi) kullanıyorum, ancak çerez ayarlamaya gelince, çalışmıyor. bu konuda yardımcı olacak kadar nazik olur musun?
KAmit

6

Kullanıyorum spring boot 2.1.0ve benim için işe yarayan şeydi

A. Korseler eşlemelerini şu şekilde ekleyin:

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

B. HttpSecurityBahar güvenliği için aşağıdaki yapılandırmayı ekle

.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;
    }
})

Ayrıca bir Zuul proxy'si olması durumunda, INSTEAD OF A ve B'yi kullanabilirsiniz ( HttpSecurity.cors()Spring güvenliğinde etkinleştirmek için kullanın ):

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

yeni CorsFilter (kaynak) döndür; böyle bir yapıcı hatası değil
Aadam

@Aadam Benimle aynı yay önyükleme sürümünü mü kullanıyorsunuz?
Eyl GH

2.1.5 kullanımda
Aadam

@Aadam Lütfen buradan CorsFilter'ı kullandığınızdan emin olun org.springframework.web.filter.CorsFilter. Yanlışlıkla katalina paketlerinden kullandığımda da aynı sorunu yaşadım.
Eyl GH

5

Bu benim için çalışıyor:

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

      //...

   }

   //...

}

Bu kod soruyu yanıtlayabilirken, bu kodun soruyu neden ve / veya nasıl yanıtladığına ilişkin ek bağlam sağlamak, uzun vadeli değerini artırır.
Adriano Martins

1
Kimlik doğrulamasının Spring güvenliği aracılığıyla etkinleştirilmesi durumunda, config.setAllowCredentials (true); Aksi takdirde CORS istekleri başarısız olmaya devam edecektir
Deepak

2

Benim için, bahar güvenliği kullanıldığında% 100 işe yarayan tek şey, fazladan filtrelerin ve fasulyelerin tüm ek tüylerini ve dolaylı "büyülü" insanlar bunun kendileri için işe yaradığını ama benim için çalışmadığını öne sürerek durmaktı.

Bunun yerine, ihtiyacınız olan başlıkları düz bir şekilde yazmaya zorlayın 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"));
    }
}

Bunu yapmak için bulduğum en doğrudan ve açık yol budur. Umarım birine yardımcı olur.


1

Bu benim için çalıştı.

@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

Aşama 1

Denetleyiciye @CrossOriginaçıklama eklemek, CORS yapılandırmalarına izin verir.

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

Adım 2

Spring zaten bir CorsFilter'e sahip olsa da, kendi konfigürasyonunuzu aşağıdaki gibi sağlamak için kendi CorsFilter'ınızı bir fasulye olarak kaydedebilirsiniz.

@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

Bunu kontrol et:

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

Bu kod soruyu yanıtlayabilirken, bu kodun soruyu neden ve / veya nasıl yanıtladığına ilişkin ek bağlam sağlamak, uzun vadeli değerini artırır.
rollstuhlfahrer

0

@EnableWebSecurity sınıfınızda WebSecurityConfigurerAdapter sınıfını genişletmek ve configure () yöntemini geçersiz kılmak işe yarayacaktır: Aşağıda örnek sınıf verilmiştir

@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

Başlangıçta programınız yay güvenliğini kullanmıyorsa ve bir kod değişikliğini karşılayamıyorsa, basit bir ters proxy oluşturmak işe yarayabilir. Benim durumumda, aşağıdaki konfigürasyonla Nginx kullandım:

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

Programım dinliyor : 8080 .

REF: Nginx'te CORS


0

Bu cevap, @abosancic cevabını kopyalar ancak CORS istismarını önlemek için ekstra güvenlik sağlar. .

İpucu 1: Erişime izin verilen ana bilgisayarların listesini kontrol etmeden, gelen Kaynağı olduğu gibi yansıtmayın.

2. İpucu: Yalnızca beyaz listedeki ana makineler için kimlik bilgilerine sahip isteğe izin verin.

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

Spring Boot uygulamamızda, CorsConfigurationSource'u bu şekilde kurduk.

allowedOrignsÖnce ekleme sırası ve sonra ayarlama applyPermitDefaultValues(), Spring'in izin verilen başlıklar, açık başlıklar, izin verilen yöntemler vb. İçin varsayılan değerleri ayarlamasına izin verin, böylece bunları belirtmemiz gerekmez.

    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

Sadece tek bir sınıf yapın , bununla her şey yoluna girecek:

        @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

Spring boot ve React arasında CORS'u devre dışı bırakmak için benim için çalışan şey buydu

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

Güvenlik yapılandırmasını da aşağıdaki gibi değiştirmek zorunda kaldım:

        @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());
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.