Spring Security CORS 过滤器不起作用
Posted
技术标签:
【中文标题】Spring Security CORS 过滤器不起作用【英文标题】:Spring Security CORS filter not working 【发布时间】:2016-11-10 01:13:07 【问题描述】:我正在使用带有 OAuth2(版本:4.0.4.RELEASE)和 spring(版本:4.3.1.RELEASE)的 Spring Security。
我正在使用 Angular 开发前端,并且正在使用 grunt connect:dev (http://127.0.0.1:9000)。当我尝试通过本地主机地址登录时,一切正常,但从其他我收到错误:
“XMLHttpRequest 无法加载 http://localhost:8084/oauth/token?client_id=MY_CLIENT_ID。对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' 标头。因此不存在来源 'http://127.0.0.1:9000'允许访问。响应的 HTTP 状态代码为 401。"
我已经在 WebMvcConfigurerAdapter 中配置了映射(Overrided public void addCorsMappings(CorsRegistry registry))(如下所示),但它仍然不适用于http://127.0.0.1:9000。
registry.addMapping("/**")
.allowedOrigins("http://127.0.0.1:9000")
.allowedMethods("POST", "OPTIONS", "GET", "DELETE", "PUT")
.allowedHeaders("X-Requested-With,Origin,Content-Type,Accept,Authorization")
.allowCredentials(true).maxAge(3600);
配置基于:https://spring.io/guides/gs/rest-service-cors/
请给我指出正确的方向来解决这个问题。
【问题讨论】:
如果我理解正确,您正在尝试从不同的 ip 127.0.0.1 访问。 (您不再在本地主机中)。但是您只允许从 localhost (127.0.0.1) 访问 Spring CORS No 'Access-Control-Allow-Origin' header is present的可能重复 Periklis - 是的,我正在尝试从不同的 IP 访问。我只能从localhost:8084 获得许可。 Oleg Kurbatov - 谢谢,我知道这个链接,但所有内容都来自文档。我完成了文档中的所有操作,但仍然无法正常工作。在我的配置中,我不使用 web.xml 订购过滤器怎么样?有什么想法吗? 【参考方案1】:下面对我有用。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
【讨论】:
【参考方案2】:抱歉长时间回复。我通过如下配置我的 CORS 过滤器解决了这个问题:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter
private static final Logger LOGGER = LogManager.getLogger(CORSFilter.class.getName());
@Override
public void init(FilterConfig filterConfig) throws ServletException
@Override
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
final String origin = ((HttpServletRequest) req).getHeader("Origin");
if (ofNullable(origin).isPresent() && origin.equals("http://127.0.0.1:9000"))
LOGGER.info("CORSFilter run");
response.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:9000");
response.addHeader("Access-Control-Allow-Credentials", "true");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod()))
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Authorization");
response.setStatus(200);
chain.doFilter(addNessesaryHeaders(request), response);
private MutableHttpServletRequest addNessesaryHeaders(final HttpServletRequest request)
final MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
mutableRequest.putHeader("Accept", "application/json");
mutableRequest.putHeader("Authorization", "Basic" + " bXVzaWNzY2hvb2w6");
return mutableRequest;
@Override
public void destroy()
【讨论】:
【参考方案3】:希望您很久以前就找到了答案,但如果没有(如果其他人发现这个问题像我一样搜索):
问题在于 Spring Security 使用过滤器进行操作,这些过滤器通常优先于用户定义的过滤器、@CrossOrigin
和类似的注释等。
对我有用的是将 CORS 过滤器定义为具有最高优先级的 bean,正如 here 所建议的那样。
@Configuration
public class MyConfiguration
@Bean
public FilterRegistrationBean corsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://127.0.0.1:9000");
config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
【讨论】:
帮我解决了问题。但是,FilterRegistrationBean
是参数化的【参考方案4】:
你可以试试这样的
@Configuration
public class CorsConfig
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedMethods(HttpMethod.OPTIONS.name(),
HttpMethod.PATCH.name(),
HttpMethod.PUT.name(),
HttpMethod.DELETE.name(),
HttpMethod.GET.name(),
HttpMethod.POST.name())
.maxAge(360);
;
注意:Spring 版本应为 4.2 或更高版本
【讨论】:
你可以尝试添加:.allowedHeaders("header1", "header2")
,接受头变量发送到服务器。
您的问题解决了吗?如果是,请您提供解决方案,即使我在我的应用程序中也面临同样的错误。以上是关于Spring Security CORS 过滤器不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Security 过滤器中授权 CORS
Tomcat CORS 过滤器和 Spring Security
spring security CORS 过滤器允许没有“Origin”标头的请求
身份验证过滤器之前的 CORS 过滤器 - 不太安全? Spring Security 过滤器链序