Spring Boot和AngularJS的CORS不起作用


87

我正在尝试从另一个(angularjs)调用一个应用程序(spring-boot应用程序)上的REST端点。这些应用程序正在以下主机和端口上运行。

  • REST应用程序,使用Spring Boot, http://localhost:8080
  • HTML应用程序,使用angularjs, http://localhost:50029

我还使用spring-security了spring-boot应用程序。我可以从HTML应用程序向REST应用程序进行身份验证,但是此后,我仍然无法访问任何REST端点。例如,我有一个定义如下的angularjs服务。

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控制器如下所示。

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

在致电时http://localhost:8080/api/admin/isloggedin,我收到了401 Unauthorized

在REST应用程序方面,我有一个CORS过滤器,如下所示。

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

我的spring安全配置如下所示。

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

处理程序所做的所有工作都是{success: true}根据用户是否登录,身份验证失败或注销来写出JSON响应。在RestAuthenticationEntryPoint如下所示。

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

}

关于我缺少或做错的任何想法?


我想您还需要进行身份验证,例如令牌之类的东西。您有2台服务器。您看过该教程了吗?spring.io/guides/tutorials/spring-security-and-angular-js
戈汉·奥纳

@GokhanOner如何进行身份验证?这可能是该问题缺少的部分。另外,是的,我确实浏览了这些教程,并且认为它们与我的方法不符。前两部分处理Http-Basic身份验证,然后第三部分处理Redis(我不想或不打算将其作为依赖项),然后最后一个教程是关于API Gatewayspring cloud的,我认为这太过分了。
简·韦恩

我想您可以不用redis就可以做到,它只是一个键值缓存存储。您需要将身份验证和CSRF令牌存储在商店中,并且可能在运行中的内部地图中。这里的关键是身份验证密钥。查看示例:github.com/dsyer/spring-security-angular/tree/master/… 以及带有“资源服务器”的页面。您将看到定义了一些其他bean,CORS过滤器的顺序也很重要。还有一些道具。更改也是必要的。
Gokhan Oner

好的,我进行了快速研究。要摆脱Redis,您需要做的是创建一个springSessionRepositoryFilter bean,查看github.com/spring-projects/spring-session/blob/1.0.0.RC1/…,还有sessionRepository bean和该bean,可以使用SpringSession中的MapSessionRepository来代替RedisOperationsSessionRepository。然后按照示例。
Gokhan Oner

Answers:


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

}

无需额外定义此过滤器,只需添加此类。Spring将被扫描并为您添加它。SimpleCORSFilter。这是示例:spring-enable-cors


几个问题。1)我应该在哪里把字符串常量HEADERSX_REDIRECT_LOCATION_HEADER?2)该行是否request.getRequestURL());有错字或复制/粘贴错误?3)为什么不检查OPTIONS过滤链,而直接继续?
简·韦恩

2
但是它阻止了执行AuthenticationEntryPoint的操作。.请引导
Pra_A 2015年

1
非常感谢您,这对我争取春天和余烬共同努力的努力提供了极大的帮助。队友的欢呼声!
Tomasz Szymanek

FindBugs不喜欢通过以下方式设置标头参数:request.getHeader("Origin")如上所示,因为HTTP响应拆分
Glenn

3
如果您的应用程序中还有其他过滤器,则该过滤器需要具有最高的优先级,方法是使用注释该过滤器@Order(Ordered.HIGHEST_PRECEDENCE)
Shafiul

43

我也遇到过类似的情况。经过研究和测试之后,这是我的发现:

  1. 使用Spring Boot时,建议启用全局CORS的方法是在Spring MVC中声明并与以下细粒度@CrossOrigin配置结合使用:

    @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. 现在,由于您使用的是Spring Security,因此还必须在Spring Security级别启用CORS,以使其能够利用Spring MVC级别定义的配置,如下所示:

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

    是一个非常出色的教程,解释了Spring MVC框架对CORS的支持。


3
ups可以处理此更改http .csrf().disable().cors()
and

1
@Osgux很高兴听到:),因为我使用JWT进行授权,而且它们是csrf安全的,所以我没有把它放在那儿..如果它有所帮助,请不要忘记投票:)
Yogen Rai

是的,我加了+1 = D
marti_

@Marcel您遇到什么问题?
Yogen Rai

无法加载<我的休息地址>:对预检请求的响应未通过访问控制检查:请求的资源上不存在“ Access-Control-Allow-Origin”标头。因此,不允许访问源' localhost:8090 '。
Marcel

22

如果要在不使用过滤器或没有配置文件的情况下启用CORS,只需添加

@CrossOrigin

到您的控制器顶部,并且可以正常工作。


4
遵循这种方法会有哪些安全隐患?
Balaji Vignesh

为我工作,我尝试直接向响应添加标头,但由于未处理预检,因此该标不起作用。我认为这是不安全的,但某些内部应用程序可能会使用它。
amisiuryk

为我工作。内部应用程序非常方便的解决方案。
阿杰·库玛

8

要基于上述其他答案,如果您具有具有Spring安全性的Spring boot REST服务应用程序(非Spring MVC),则通过Spring安全性启用CORS就足够了(如果您使用Spring MVC,则可以使用WebMvcConfigurerYogen提到的bean) Spring安全性将委托给其中提到的CORS定义)

因此,您需要具有执行以下操作的安全性配置:

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

}

该链接具有相同的更多信息:https : //docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors

注意:

  1. 为产品部署的应用程序的所有来源(*)启用CORS并非总是一个好主意。
  2. 可以通过Spring HttpSecurity定制启用CSRF,而不会出现任何问题
  3. 如果您使用Spring在应用中启用了身份验证(UserDetailsService例如通过a ),则configuration.setAllowCredentials(true);必须添加

经过Spring Boot 2.0.0.RELEASE的测试(即Spring 5.0.4.RELEASE和Spring Security 5.0.3.RELEASE)


这解决了我的问题。作为Spring和Spring Boot的新手,我意识到我没有使用Sring MVC进行构建。我有一个Vue.js客户端。其他答案似乎是针对Spring MVC的,但是这个答案与我已经实现的身份验证和授权很好地结合在一起。
jaletechs

嗨@jaletechs,我也使用nuxtJs(一个vuejs框架),但是在设置cookie时,它不起作用。您愿意在这方面提供帮助吗?
卡米(Kamit)

6

我正在使用spring boot 2.1.0,对我有用的是

A.通过以下方式添加cors映射:

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

B.为我HttpSecurity的弹簧安全性添加以下配置

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

同样在Zuul代理的情况下,您可以使用此INSTEAD OF A和B(仅用于HttpSecurity.cors()在Spring安全性中启用它):

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

返回新的CorsFilter(source); 不是这样的构造函数错误
Aadam

@Aadam您是否使用与我相同的Spring Boot版本?
9

2.1.5正在使用
Aadam

@Aadam不幸的是,这可能是原因。
9

@Aadam请确保您使用的CorsFilter org.springframework.web.filter.CorsFilter。我偶然从catalina软件包中使用它时遇到了同样的问题。
9

5

这对我有用:

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

      //...

   }

   //...

}

尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以改善其长期价值。
阿德里亚诺·马丁斯

1
如果通过Spring安全性启用了身份验证,则config.setAllowCredentials(true); 必须放置,否则CORS请求仍将失败
Deepak

2

对我来说,使用Spring Security时,唯一有效的方法就是跳过所有额外的过滤器和bean绒毛,而任何间接的“魔术师”都坚持认为对他们有效,但对我却无效。

相反,只需强制它用普通的格式编写所需的标题即可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"));
    }
}

这是我发现的最直接,最明确的方法。希望它能帮助某人。


1

步骤1

通过使用注释对控制器进行@CrossOrigin注释,将允许进行CORS配置。

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

第2步

即使您可以将自己的CorsFilter注册为Bean来提供您自己的配置,Spring也已经具有CorsFilter。

@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

检查这一:

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

尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以提高其长期价值。
rollstuhlfahrer

0

扩展WebSecurityConfigurerAdapter类并在@EnableWebSecurity类中覆盖configure()方法将起作用:以下是示例类

@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

如果最初您的程序不使用spring安全性并且负担不起代码更改,那么创建简单的反向代理就可以解决问题。就我而言,我将Nginx用于以下配置:

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

我的程序听:8080

参考:Nginx上的CORS


0

这对我有用。

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

}

0

该答案复制了@abosancic答案,但增加了额外的安全性,以避免CORS被利用

提示1:在未检查允许访问的主机列表的情况下,请勿按原样反映传入的Origin。

提示2:仅对列入白名单的主机允许凭据请求。

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应用程序中,我们像这样设置了CorsConfigurationSource。

通过allowedOrigns先添加然后设置的顺序,applyPermitDefaultValues()Spring可以为允许的标题,暴露的标题,允许的方法等设置默认值,因此我们不必指定这些默认值。

    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

像这样制作一个,一切都会很好:

        @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和React之间禁用CORS

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

我还必须修改安全性配置,如下所示:

        @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());
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.