我使用Nginx作为Spring启动应用程序的反向代理,还使用带有sockjs和stomp消息的Websockets。
下面是上下文配置。
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/localization" >
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic" />
</websocket:message-broker>
下面是客户端代码:
var socket = new SockJS(entryPointUrl);
var stompClient = Stomp.over(socket);
var _this = this;
stompClient.connect({}, function () {
stompClient.subscribe('/app/some-url', function (message) {
// do some stuff
});
});
我也是你们Spring Security保护的一些内容。
@Configuration
@Order(4)
public static class FrontendSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/js/**", "/css/**", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
}
一切都运行得很好,除了当我在Nginx反向代理后面运行这个应用程序时。
proxy_pass http://testsysten:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support (nginx 1.4)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
# Max body size
client_max_body_size 10M;
连接总是失败,并显示HTTP 403代码。
我用的是1.9.7版。
你知不知道,为什么客户端没有得到认证?
我知道类似的问题,像this one,但解决方案根本不起作用。
更新
我设法通过HTTP运行应用程序。我需要在Nginx配置中传递CSRF令牌。新配置是:
proxy_pass http://testsysten:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Pass the csrf token (see https://de.wikipedia.org/wiki/Cross-Site-Request-Forgery)
# Default in Spring Boot
proxy_pass_header X-XSRF-TOKEN;
# WebSocket support (nginx 1.4)
proxy_http_version 1.1;
唯一缺少的是通过HTTPS重定向。在Spring日志中,可看到以下条目:
o.s.w.s.s.t.h.DefaultSockJsService - Processing transport request: GET http://testsystem:80/localization/226/3mbmu212/websocket
似乎Nginx代理需要重写到正确的端口。
5条答案
按热度按时间2cmtqfgy1#
我自己解决了这个问题。基本上,如果你想使用WebSocket和Spring Security,Nginx需要传递一些额外的头值。下面几行需要添加到你的Nginx配置中的
location
部分:qncylg1j2#
虽然我使用的是非常经典的HTTPS配置,但公认的解决方案对我不起作用:
问题是Spring检查源代码,特别是给我带来麻烦的代码:
在该代码中,方案是“http”,端口是8888,由于它不是标准端口,因此未被丢弃。
但是浏览器点击https://myserver/,443端口被忽略,因为它是默认的HTTPS端口。
因此,端口不匹配(空!= 8888),并且来源检查失败。
您可以在Spring WebSockets中禁用来源检查:
或者(可能更安全)您可以将方案和端口添加到NGINX代理配置中:
如果您感兴趣,可以读取这些标题
适用于 Spring Boot 2.2.2+
从Sping Boot 版本2.2.2开始,您应添加以下设置,以便考虑这些
X-Forwarded-*
标头:(in例如
application.properties
)bd1hkmkf3#
我也遇到过类似的问题,我无法在NGINX上使用基本的Spring Security身份验证,除了设置
proxy_pass_header X-XSRF-TOKEN;
之外,我还必须设置underscores_in_headers on;
,因为NGINX默认不允许头标带有下划线,CSRF令牌名为_csrf
。我的最终配置文件如下所示:
8wigbo564#
我在NGINX代理中没有CSRF报头的情况下解决了这个问题。
我的堆栈:spring-boot,spring-security(带有redis会话存储),spring-boot-WebSocket with default STOMP implementation,NGINX服务于前端并代理到前端使用的另一个服务。
在我第一次使用default configuration show in the NGINX Blog here和这里(复制和粘贴历史):
但不工作,仍然403禁止。
我用下面的配置修复了这个问题(修复WebSocket真实的重要的部分是 *# WebSocket代理 *):
uqcuzwp85#
在我的例子中(Sping Boot 应用程序),除了按照接受的答案中指定的那样设置
Origin
头之外,我还必须设置Host
头以匹配Origin
头的ip:port,或者完全去掉它。这是我的工作vhost配置: