首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当请求的凭据模式为'include‘时,响应中的标头不能是通配符'*’

当请求的凭据模式为'include‘时,响应中的标头不能是通配符'*’
EN

Stack Overflow用户
提问于 2017-03-30 18:09:22
回答 3查看 107.3K关注 0票数 43

我使用Auth0进行用户身份验证,只允许登录的用户访问Spring (Boot) RestController。此时,我正在创建一个实时消息功能,用户可以在其中使用stompjssockjs将消息从Angular 2客户机(localhost:4200)发送到Spring服务器(本地主机:8081)。

在尝试创建Stomp-client并启动连接时,我收到以下控制台错误:

代码语言:javascript
运行
复制
 The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:4200' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

研究此问题后,似乎不可能同时设置选项origins =*和credentials = true。当我已经在WebSocketConfig中将允许的源设置为客户端域时,如何解决此问题?

角度2分量

代码语言:javascript
运行
复制
connect() {
    var socket = new SockJS('http://localhost:8081/chat');
    this.stompClient = Stomp.over(socket);  
    this.stompClient.connect({}, function(result) {
        console.log('Connected: ' + result);
        this.stompClient.subscribe('/topic/messages', function(message) {
            console.log(message);
        });
    });
}    

WebSocketConfig

代码语言:javascript
运行
复制
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:4200").withSockJS();
    }
}

本地主机:8081/chat/info?t=1490866768565

代码语言:javascript
运行
复制
{"entropy":-1720701276,"origins":["*:*"],"cookie_needed":true,"websocket":true}

MessageController

代码语言:javascript
运行
复制
public class MessageController {
    @MessageMapping("/chat")
    @SendTo("/topic/messages")
    public Message send(Message message) throws Exception {
        return new Message(message.getFrom(), message.getText());
    }
}

SecurityConfig (临时允许全部)

代码语言:javascript
运行
复制
public class SecurityConfig extends Auth0SecurityConfig {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().permitAll();
    }
}

更新

经过进一步的测试和研究,这个问题似乎只有在使用Chrome时才会出现。问题可能与:https://github.com/sockjs/sockjs-node/issues/177有关

更新

我创建了chsdk提到的CORSFilter,并使用了addFilterBefore()方法:https://stackoverflow.com/a/40300363/4836952

代码语言:javascript
运行
复制
@Bean
CORSFilter corsFilter() {
    CORSFilter filter = new CORSFilter();
    return filter;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(corsFilter(), SessionManagementFilter.class).authorizeRequests().anyRequest().permitAll();
    http.csrf().disable();
}

我可以看到,过滤器是通过调试调用的,但即使设置了正确的Access-Control-Allow-Origin,错误消息也一直出现在客户端:

EN

回答 3

Stack Overflow用户

发布于 2017-04-14 16:32:27

这与您的spring或angular应用程序代码无关。

问题的简介

Access-Control-Allow-Origin是CORS (跨域资源共享)机制的一部分,该机制为web服务器提供跨域访问控制。它可以保护您的应用程序/站点免受CSRF (跨站点请求伪造)的攻击。

CORS / CSRF

The problem

现在如果我们仔细阅读你的错误

代码语言:javascript
运行
复制
The value of the 'Access-Control-Allow-Origin' header in the response must 
not be the wildcard '*' when the request's credentials mode is 'include'. 
Origin 'http://localhost:4200' is therefore not allowed access.

它说明Access-Control-Allow-Origin报头不能是通配符。

换句话说,现在你的后端是说来自网络各地的每个人都可以在我的网站上运行代码。

我们想要实现的:限制来源仅限于您的前端应用程序(ng2)。

Solution现在,因为您使用的是Spring,所以我将假定您将它与Apache Tomcat一起使用作为后端with服务器。

CORS被定义为web.conf (tomcat文件夹)中的过滤器

找到这一行

代码语言:javascript
运行
复制
<init-param>
  <param-name>cors.allowed.origins</param-name>
  <param-value>*</param-value>
</init-param>

并将*更改为http://localhost:4200

有关Tomcat please read this中CORS配置的详细信息,请参阅

编辑( Spring boot )

因为您使用的是spring boot,所以可以将cors的配置委托给框架。

请关注this tutorial on spring.io (就像chsdk建议的那样),以更好地掌握使用spring boot的CORS配置。

票数 6
EN

Stack Overflow用户

发布于 2018-02-19 03:07:05

我的回答太晚了,但我发布了这篇文章,如果有人能面临同样的问题,我也一直面临着同样的跨来源问题。

基本上,如果您使用在服务器端应用程序上实现的Spring Security,那么很可能是他阻止了websocket握手程序

为了允许套接字握手,您必须告诉Spring security允许您的websocket端点...使用

代码语言:javascript
运行
复制
.antMatchers("/socket/**").permitAll()

因此,sockjs现在可以在切换到Websocket协议之前发送GET (Http)请求进行握手

这是安全配置

代码语言:javascript
运行
复制
package org.souhaib.caremy.security.module.config;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint).and()
            .authorizeRequests()
            .antMatchers(SecurityParams.PUBLIC_ROUTES).permitAll()
            .antMatchers("/socket/**").permitAll();

    http.csrf().disable();
}}

这是WebSocket Broker configuration

代码语言:javascript
运行
复制
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket")
                .setAllowedOrigins("http://localhost:4200")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app")
                .enableSimpleBroker("/chat");
    }
}
票数 3
EN

Stack Overflow用户

发布于 2017-07-03 19:11:35

只需在webSocket配置中添加.setAllowedOrigins("*")即可。

代码语言:javascript
运行
复制
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
    stompEndpointRegistry.addEndpoint("/yourEndpoint");
    stompEndpointRegistry.addEndpoint("/yourEndpoint").setAllowedOrigins("*").withSockJS();
}

webSocket的版本是1.4.1.RELEASE,如果没有显示该方法,您应该更新版本。

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43114750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档